[][src]Function tao_of_rust::ch08::strings::strings

pub fn strings()

字符串String

Base usage: 组成String的三部分展示

  1. 指向堆中字节序列的指针(as_ptr方法)
  2. 记录堆中字节序列的字节长度(len方法)
  3. 堆分配的容量(capacity方法)
fn main() {
    let mut a = String::from("fooα");
    println!("{:p}", a.as_ptr());
    println!("{:p}", &a);
    assert_eq!(a.len(), 5);
    a.reserve(10);
    assert_eq!(a.capacity(), 15);
}Run

Base usage: 创建字符串的各种方法

fn main() {
    let string: String = String::new();
    assert_eq!("", string);
    let string: String = String::from("hello rust");
    assert_eq!("hello rust", string);
    let string: String = String::with_capacity(20);
    assert_eq!("", string);
    let str: &'static str = "the tao of rust";
    let string: String =
       str.chars().filter(|c| !c.is_whitespace()).collect();
    assert_eq!("thetaoofrust", string);
    let string: String = str.to_owned();
    assert_eq!("the tao of rust", string);
    let string: String = str.to_string();
    let str: &str = &string[11..15];
    assert_eq!("rust", str);
}Run

Base usage: chars和bytes方法展示

字符串的操作大致分为两种方式:按字节处理和按字符处理

fn main() {
    let str = "borös";
    let mut chars = str.chars();
    assert_eq!(Some('b'), chars.next());
    assert_eq!(Some('o'), chars.next());
    assert_eq!(Some('r'), chars.next());
    assert_eq!(Some('ö'), chars.next());
    assert_eq!(Some('s'), chars.next());
    let mut bytes = str.bytes();
    assert_eq!(6, str.len());
    assert_eq!(Some(98), bytes.next());
    assert_eq!(Some(111), bytes.next());
    assert_eq!(Some(114), bytes.next());
    assert_eq!(Some(195), bytes.next());
    assert_eq!(Some(182), bytes.next());
    assert_eq!(Some(115), bytes.next());
}Run

Base usage: 使用get和get_mut

字符串不能按index来字节访问字符,所以需要get和get_mut

fn main() {
    let mut v = String::from("borös");
    assert_eq!(Some("b"), v.get(0..1));
    assert_eq!(Some("ö"), v.get(3..5));
    assert_eq!(Some("orös"), v.get(1..));
    assert!(v.get_mut(4..).is_none()); // 访问了非法的utf8序列
    assert!(!v.is_char_boundary(4)); // 验证字符是否属于合法边界
    assert!(v.get_mut(..8).is_none());
    assert!(v.get_mut(..42).is_none());
}Run

Base usage: 使用split_at和split_at_mut切割字符串

需要注意字符串的合法边界

fn main() {
    let s = "Per Martin-Löf";
    let (first, last) = s.split_at(12);
    assert_eq!("Per Martin-L", first);
    assert_eq!("öf", last);
    // 'main' panicked:byte index 13 is not a char boundary
    // let (first, last) = s.split_at(13);
}Run

Base usage: 追加字符串

fn main() {
    let mut hello = String::from("Hello, ");
    hello.push('R');
    hello.push_str("ust!");
    assert_eq!("Hello, Rust!", hello);
}Run

Base usage: 使用extend迭代器追加字符串

fn main() {
    let mut message = String::from("hello");
    message.extend([',', 'r', 'u'].iter());
    message.extend("st ".chars());
    message.extend("w o r l d".split_whitespace());
    assert_eq!("hello,rust world", &message);
}Run

Base usage: 使用insert和insert_str插入字符串

fn main() {
    let mut s = String::with_capacity(3);
    s.insert(0, 'f');
    s.insert(1, 'o');
    s.insert(2, 'o');
    s.insert_str(0, "bar");
    assert_eq!("barfoo", s);
}Run

Base usage: 字符串连接

fn main() {
    let left = "the tao".to_string();
    let mut right = "Rust".to_string();
    assert_eq!(left + " of " + &right, "the tao of Rust");
    right += "!";
    assert_eq!(right, "Rust!");
}Run

Base usage: 更新字符串

use std::ascii::{AsciiExt};
fn main() {
    let s = String::from("fooαbar");
    let mut result = s.into_bytes();
    (0..result.len()).for_each( |i|
        if i % 2 == 0 {
            result[i] = result[i].to_ascii_lowercase();
        }else {
            result[i] = result[i].to_ascii_uppercase();
        }
   );
   assert_eq!("fOoαBaR", String::from_utf8(result).unwrap());
}Run

Base usage: 按字符迭代处理字符串

fn main() {
    let s = String::from("fooαbar");
    let s: String = s.chars().enumerate().map(|(i, c)| {
        if i % 2 == 0 {
            c.to_lowercase().to_string()
        } else {
            c.to_uppercase().to_string()
        }
    }).collect();
   assert_eq!("fOoΑbAr", s);
}Run

Base usage: 字符串删除

fn main() {
    let mut s = String::from("hαllo");
    s.remove(3);
    assert_eq!("hαlo", s);
    assert_eq!(Some('o'), s.pop());
    assert_eq!(Some('l'), s.pop());
    assert_eq!(Some('α'), s.pop());
    assert_eq!("h", s);
    let mut s = String::from("hαllo");
    s.truncate(3);
    assert_eq!("hα", s);
    s.clear();
    assert_eq!(s, "");
    let mut s = String::from("α is alpha, β is beta");
    let beta_offset = s.find('β').unwrap_or(s.len());
    let t: String = s.drain(..beta_offset).collect();
    assert_eq!(t, "α is alpha, ");
    assert_eq!(s, "β is beta");
    s.drain(..);
    assert_eq!(s, "");
}Run