【编程】Rust语言入门第4篇 字符串

Rust 中的字符是 Unicode 类型,因此每个字符占据 4 个字节内存空间,但字符串不一样,字符串是 UTF-8 编码,也就是字符串中的字符所占的字节数是变化的(1 - 4)。
常见的字符串有两种:

  1. str,通常是引用类型,&str,即字符串字面常量,字符串切片。
  2. std::string::String
    类型&str的变量是被硬编码的,快速而高效,但不可变;类型String,是可设可变的,它是在堆上的变量,如何管理内存,有的语言用垃圾回收机制(Garbage Collection),标记使用情况并自动清理;而Rust不愿意用GC,既要高性能,又要高安全性,提出变量离开作用域即自动释放其占用的内存,比GC思路更妙。
    C语言中清理内存的函数free,要被手动调用;Rust中则是drop(),Rust自动调用。
    C++中的Resoure Acquisition Is Initialization,RAII模型。

两种字符串类型互转

&strString:

let a = String::from("hello, world");
"hello, world".to_string();

String&str,引用即可

fn main() {
   
    let s = String::from("hello,world!");
    say_hello(&s);
    say_hello(&s[..]);
    say_hello(s.as_str());
}

fn say_hello(s: &str) {
   
    println!("{}",s);
}

除上述两种类型,Rust标准库还有其他类型的字符串。

字符串不能被直接索引

Rust字符串不允许索引操作。由于不同字符占用字节数不等,考虑操作时间复杂度不能实现O(1)。

//三个字节
let a = "中国人";
//一个字节
let b = "Chinese";

Rust字符串虽然不能索引但可以切片(slice),类似Python等语言中的切片概念。

fn main() {
   
    let my_name = "kirk zhang";
    let first_name = &my_name[0..4];
    let last_name = &my_name[5..10];
    println!("{}",first_name);
    println!("{}",last_name);
    greet(String::from(my_name));
    // 尝试my_name[0]报错,不过可以用.chars().nth或.bytes()来实现
    println!("can str be indexed {:?}",my_name.chars().nth(0));
}

fn greet(name: String){
   
    println!("hello {}", name);
}

小心字符串切片

注意字符串切片是按字节来的哦,而Rust字符串是UTF-8协议格式,一般1个字符1个字节,但1个中文字符占3个字节;如果切片起止不在字符边界,则有异常。

fn main(){
   
    let f = "中国人";
    let f1 = &f[0..5];
    println!("watch out, what you got {}",f1);
}

提示:thread ‘main’ panicked at ‘byte index 5 is not a char boundary; it is inside ‘国’ (bytes 3…6) of 中国人’, src/main.rs:10:15
note: run with RUST_BACKTRACE=1 environment variable to display a backtrace

字符串的操作

替换

replace(要被替换的子串,新字符串),返回结果字符串。

    let word = String::from("rust");
    let new_word = word.replace("r","R");
    println!("{}", new_word);

插入

insert(位置索引,字符)、insert_str(位置索引,字符串):变量本身变化,声明时要mut。

    let word = String::from("rust");
    let mut new_word = word.replace("r","R");
    new_word.insert_str(0, "I love ");
    println!("{}", new_word);

追加

push(字符)
push_str(字符串)

    let word = String::from("rust");
    let mut new_word = word.replace("r","R");
    new_word.insert_str(0, "I love ");
    new_word.push('!');
    println!("{}", new_word);   

连接

++= 调用了String的add(self,&str)方法,其定义要求+后面的参数为字符串字面常量,返回String类型。
或用format! ,适用于 String 和 &str 。format! 的用法与 println! 的用法类似。

let a1 = String::from("tic");
let a2 = String::from("tac");
let a3 = String::from("toe");

// 经过下面一行后,a1被释放了,不能再使用!a2、a3依然存在。
let s = s1 + "-" + &s2 + "-" + &s3;

删除

有4个方法,pop()、remove(索引位置)、truncate(起始位置)、clear()
注意删除字符串的索引必须是字符串中字符的边界,否则错误。

fn main() {
   
    let mut string_remove = String::from("测试remove方法");
    println!(
        "string_remove 占 {} 个字节",
        std::mem::size_of_val(string_remove.as_str())
    );
    // 删除第一个汉字
    string_remove.remove(0);
    // 下面代码会发生错误
    // string_remove.remove(1);
    // 直接删除第二个汉字
    // string_remove.remove(3);
    dbg!(string_remove);
}

字符串的字符与字节

例,

   for c in "中国人".chars() {
   
       println!("{}", c);
   }
   for b in "中国人".bytes() {
   
       println!("{}", b);
   }

相关推荐

  1. 编程Rust语言门第4 字符串

    2024-02-18 13:36:04       51 阅读
  2. Rust语言门第-函数

    2024-02-18 13:36:04       32 阅读
  3. Python门第5(爬虫相关)

    2024-02-18 13:36:04       68 阅读
  4. c门第十一——物以类聚(数组)

    2024-02-18 13:36:04       53 阅读
  5. c门第十六——学生成绩管理系统

    2024-02-18 13:36:04       51 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-02-18 13:36:04       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-02-18 13:36:04       100 阅读
  3. 在Django里面运行非项目文件

    2024-02-18 13:36:04       82 阅读
  4. Python语言-面向对象

    2024-02-18 13:36:04       91 阅读

热门阅读

  1. React中hooks使用限制及保存函数组件状态

    2024-02-18 13:36:04       49 阅读
  2. Rust 学习笔记 - 流程控制 与 Range 类型

    2024-02-18 13:36:04       53 阅读
  3. AWS认证SAA-C03每日一题

    2024-02-18 13:36:04       42 阅读
  4. https 为什么安全

    2024-02-18 13:36:04       58 阅读
  5. CDF和PDF的比较

    2024-02-18 13:36:04       45 阅读
  6. MCU中断里使用软延时函数delay_ms(u16 x)问题探讨:

    2024-02-18 13:36:04       48 阅读
  7. 工作心得——css让元素居中的方法

    2024-02-18 13:36:04       54 阅读
  8. devc++ 使用 winsock 实现 UDP 广播

    2024-02-18 13:36:04       58 阅读