5.rust字符串String详解

一、前言

rust中的String是一个非常常用的crate,它的底层涉及到了rust中的所有权概念,不过这不是本章的内容,如果对rust所有权概念感兴趣的,可以查看前一篇文章:String与所有权

本文的目的是详细、全面的介绍String的基本用法,毕竟它实在是太过常用了,自带了大量的方法。

二、基本概念

字符串,也就是由一系列字符组成的,而在计算机中存储一个字符,用到的字节数量并不完全相同。

比如下面的代码:

fn main() {
    let s1=String::from("h");
    let s2=String::from("你");
    println!("{} {}",s1.len(),s2.len());
}

同样是一个字符,只不过s1是英文字符,s2是中文字符,所使用的空间就不是一样大:

1 3

一个英文字符用1个字节大小,而一个中文字符却要用3个字节大小。

之所以出现这个现象,是因为rust中的字符串String为了更加的通用化,采用的是UTF-8编码,更多介绍可参考文章:编码

正因为utf-8编码的这一特性,导致了我们无法像c语言那样,可以直接遍历字符串中的所有字符:

fn main() {
    let s=String::from("hello 世界");
    for i in s{ //错误,无法直接遍历

    }
}

同样的,你也无法直接用下标取出对应的字符

fn main() {
    let s=String::from("hello 世界");
    let c=s[0]; //错误,不能直接用下标取出字符
}

因为每个字符占用的内存大小不一,所以它不知道你是想要取出字符,还是想要取这个位置上的字节。

三、构造

既然是学习String,那么第一件事就是了解我们应该怎么创建一个String,一般有三个方法:

fn main() {
    let s=String::from("hello 世界");

    let mut s1=String::new();
    s1.push_str("hello 世界");
    //s1+="hello 世界"; //与上面的语句等价,即:追加字符串在后面
    
    let s2="hello 世界".to_string();

    println!("{}", s);
    println!("{}", s1);
    println!("{}", s2);
}

三个方法分别是调用from函数、new函数以及to_string函数。

其中,fromto_string的功能是等价的,只是调用的对象不同而已,作用都是从一个字符串字面量直接构造出一个String来。

new函数则是凭空产生一个String,并且为空,如果想要让它存值就得将他声明为可变的(mut),之后可以用push_str函数或者+=操作符来追加字符串。

最后输出的结果都是一样的:

hello 世界
hello 世界
hello 世界

除此之外,还有一个函数为with_capacity

 let s=String::with_capacity(100);

它的作用与new基本相同,唯一不同之处在于,这个函数需要一个参数来初始化其内部的内存大小,如果你事先知道自己需要多大的内存,那么建议你使用这个函数来构造一个String而不是用new

至于原因,可以参考后文的:长度与容量

四、遍历

接下来,我们首先要看的就是如何对字符串进行遍历,用到的函数为as_byteschars

首先是as_bytes函数,看名字也知道,它的意思就是:作为字节

所以它的功能就是遍历字符串的所有字节,就可以这样写:

作者:余识
全部文章:0
会员文章:0
总阅读量:0
c/c++pythonrustJavaScriptwindowslinux