返回介绍

7.4 字符串

发布于 2024-10-13 11:25:29 字数 3137 浏览 0 评论 0 收藏 0

字符串(UTF-8)相关类型,根据用途选用。

  • char : Unicode 字符(4 bytes)。
  • str : 字符串切片( [u8] ,UTF8,DST)。
  • String : 堆分配可变字符串( Vec<u8> ,UTF8)。

使用建议:

  • 字面量无法修改,对应 &str
  • 动态修改的字符串使用 String
  • 传递子串,不想要所有权,不想复制内容,用 &str&mut str

结构示意图:

  String         heap
   +=======+       +=========//========+
   | ptr   | --------> | u8 data ...     |
   +-------+       +=========//========+
   | cap   |
   +-------+
   | len   |
   +=======+
  

  &str
   +=======+       +========//========+
   | ptr   | --------> | u8 data ....   |
   +-------+       +========//========+
   | len   |
   +=======+
   
struct String {
  vec: Vec<u8> {
    buf: RawVec<u8> {
      ptr,
      cap,
    },
    len,
  }
}

struct &str {
  ptr: *mut u8,
  len: usize,
}

struct &mut str {
  ptr: *mut u8,
  len: usize,
}

字面量

静态分配(.rodata)。

  • 跨行:支持跨行。若以 \ 结尾,删除换行和前置空格。
  • 转义: "abc, \x41 \u{6211}们 \" \\"
  • 原始字符串(raw string):
    r"a\x41bc"
    r#"a"bc"# (内容包含引号),
    r##"a#"bc"## (内容包含 #,用更多的 ## 作边界)。
let s: &'static str = "hello, world!";
fn main() {
  let s = "foo\
    bar"; 

  assert_eq!("foobar", s);   // 删除换行和前置空格。
}

添加 b 前缀,表示 Byte String,同样支持转义、跨行和原始字符串( br )。

这也意味着,无法容纳 Unicode 字符。

fn main() {
  let s = b"abc";            // [u8; 3]
  assert_eq!(s, &[b'a', b'b', b'c']);

  let s = br"a\c";
  assert_eq!(s, &[b'a', b'\\', b'c']);
}

转换

根据需要,在不同类型间转换。

// char <--> integer

let i = 'A' as i32;
let c = i as u8 as char;   // char::from_u32

assert_eq!(c, 'A');
// literal -> String, heap_alloc

let mut s = 1.to_string();

let mut s = "abc".to_string();
let mut s = String::from("abc");   
// String -> &str

let mut s = String::from("abc");

// &str
let x: &str = &s;  // auto: &String to &str
let x = &s[..];
let x = s.as_str();

// &mut str
let y: &mut str = &mut s;  
let y = &mut s[..];
let y = s.as_mut_str();
// String -> Unicode Char

fn main() {
  let s = "我们".to_string();

  let c = s.chars();
  let s2 = c.as_str();

  assert_eq!(2, c.count());
  assert_eq!(s, s2);
}
// str <--> [u8]

use std::str;

fn main() {
  let s: &str = "中国";
  let b: &[u8] = s.as_bytes();
  let s2: &str = str::from_utf8(b).unwrap();

  println!("{:?}", b);
  println!("{:?}", s2);
}

操作

格式化字符串。

// format

fn main() {
  let s = format!("{}{}", "a", 1);
  assert_eq!(s, "a1");
}

连接字符串。

fn main() {
  let v = ["a", "b", "cd"];
  assert_eq!(v.concat(), "abcd");
  assert_eq!(v.join(","), "a,b,cd");
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文