先看看字符
要说字符串当然得先说字符,什么是字符呢?英文、中文、法文、所有的文字都是字符。由于计算机最早是由英美发明 ,人家发明的时候并没有考虑中国人使用方便不方便,所以,最早的字符采用了ASCII码,表达的就是英文中常用的128个字符,一个字节的空间就足够了,但是,好东西大家都想用,当其他国家也冲进计算机领域后,这种编码方式很快显示出局限性,尤其是对于拥有更多字符的欧洲语言来说。因此,需要更多的位来表示更多的字符,于是出现了扩展ASCII码,最多可表示256个字符。但是还是不够,拿中文来说,常用字3000多,加上不常用的一万多。跟本不够,于是各国都搞出来不同的字符标准,这又导致了同一个编码方式可能对应不同的字符,这在国际通信的时候简直就是灾难,所以,后来各国有科学家们开了几个会吵了无数架后,终于定了一个可以应用于全球的标准,Unicode。
做为最新的编程语言,rust支持的就是Unicode,rust的字符用一对英文状态下的单引号''
来表示,里面只能有一个字符,每个字符固定占4个字节。
如:
let a = 'a';
let b = '中';
rust的字符也自带了很多方法,比较常用的有:
- is_ascii() 判断是不是ascii码,如果是,返回true,如不是,返回false:
println!("{}",'a'.is_ascii()); //返回true
println!("{}",'京'.is_ascii()); //返回false
- is_ascii_alphabetic判断是不是应文字母(a-z,A-Z):
println!("{}",'A'.is_ascii_alphabetic());
- is_ascii_digit()判断是不是数字字符(0-9)
println!("{}",'1'.is_ascii_digit());
- to_ascii_lowercase()将英文字符转成小写。
- to_ascii_uppercase()将英文字符转成大写。
其他的先不讲,从来没用过,用到了再说。
字符串
没有谁说话是一个字一个字蹦的,所以,日常用的时候,必然是用字符串,所谓字符串,就是字符串成的串串嘛,不过串起来之后,它还把多余的空间挤了挤,这一挤节省了空间,但又导至了一定的复杂性,比如,Unicode本身并不直接涉及字符如何存储和传输的问题,这就催生了多种Unicode的实现编码方式,如UTF-8、UTF-16和UTF-32等。rust默认使用UTF-8,UTF-8是由Rob Pike和Ken Thompson共同发明的,它是一种变长编码方式,能够兼容ASCII码,也就是说,英文是ASCII,占一字节,欧洲一些字符用两字节,中文用三字节,一小部分用四字节,这使得它在网络传输和文件存储中非常有效率。
字符串在rust中,使用一对双引号表示:
let hello_world = "hello,world!";
在rust中,有一个很难让人理解的情况,就是类似"hello,world!"这种字符串,它是保存在一个叫做字符串字面量区的地方,这个地方是只读数据,也就是说,str这种字符串在程序编译的时候就写死到程序里了,所以它不能改,只能读。所以,对于hello_world的类型不是str而是对str的引用,即&str(关于引用我们后面再细细讲)。完整的写法应是:let hello_world:&str = "hello,world!";
所以,真正的hello_world是一个叫作切片的数据,它由两部分组成,一个指向字符串起始位置的指针(也就是字符串起始位的内存地址小纸条)和一个长度值。引用不妨碍我们对它的使用,照例看看它的本领。
我们先let a = "京A123";
- a.as_bytes();将字符串切片转换为u8的字节切片,返回这个:[228, 186, 172, 65, 49, 50, 51]其中,228,186,172是"京",65是"A",49,50,51分别是"1",“2”,“3”。
- a.as_bytes_mut:将字符串切片转换成可变的u8字节切片。
- a.as_ptr():返回一个指向第一个字节的祼指针,也就是返回保存228这个数据的地址编号。
- a.chars():返回字符串切片以char为单位的迭代器。什么是迭代器?我们可以把它想像成一盒香烟,迭代器是烟盒,里面的数据是烟,需要的时候,抽一支出来,抽完为止。
fn main() {
let a = "京A123";
for i in a .chars() {
println!("{}",i);
}
}
打印出来的结果是:
京
A
1
2
3
- a.contains(“A1”):检查“A1”是不是包含在A字符串中,包含返回true,不包含返回false。
- a.ends_with(“23”);检查a的结尾是不是"23",是返回true,否返回false。
- a.start_with(“冀”);检查a的开头是不是括号内的字符或字符串,返回布尔值。
- a.find(“A”);返回此字符串切片中与模式匹配的第一个字符的字节索引。这里返回的是Some(3),因为0,1,2都被“冀”占了。如果模式不匹配,返回None。
- a.get(0…3);返回
str
的子切片,这里(0…3)是0到3不包括3的意思,小心如果索引切到字的中间会返回None
。本例返回“京” - a.is_ascii();检查字符串所有的字符是否都在ASCII范围内。
- a.is_empty();如果a长度为零字切,返回true。
- a.len();返回a的字节长度,对于本例来说,它返回的不是5,而是7,因为京占了3个长度。
- a.lines();以换行符"\n"或"\n\r"为切分点对字符串进行切分,返回一个迭代器,其元素是切分后的字符串。
- a.make_ascii_lowercase();把字符串里的大写英文字母换成小写,其他不动。
- a.make_ascii_uppercase();把字符串里的小写英文字母换成大写,其他不动。
- “abcXXXabcYYYabc”.matches(“abc”);返回一个迭代器,内容是所有匹配到的"abc"。
- a.parse();将字符串解析为另一种类型,如不能解析,返回Err.
如,let str_to_u32:u32 = "43".parse()
,这个方法将字符串形式的43解析成u32格式的43,parse这个方法可以解析很多形式的数据,所以让它解析成什么取决于你指定的数据类型。 - a.repeat(4);将a所代表的字符串重复4次,生成一个新字符串。
- a.replace(“1”,“一”);将a中所有的"1"替换成"一"。生成一个新字符串。
- a.split(“1”);将括号内的字符或字符串做为分切标识,将字符串切成一段一段的,返回一个迭代器。
- a.split_axcii_whitespace();将空格、\n、\n\r等作为分切标识,将字符串切开,返回一个迭代器。
- a.split_at(3);在索引3处将字符串切开成两个字符串,当心有切不动的时候。
- a.trim();去除a前后的空格,返回一个新字符串切片。
- a.trim_left();去除a左边的空格。
- a.trim_right();去除a右边的空格。