对String按索引的形式进行访问 按索引语法访问String的某一部分会报错,例:fnmain(){lets1:StringString::from(12);lets2:Strings1〔0〕;}cargorunCompilingmyprojectv0。1。0(E:ProjectsRustmyproject)error〔E0277〕:thetypeStringcannotbeindexedby{integer}srcmain。rs:3:223lets2:Strings1〔0〕;Stringcannotbeindexedby{integer}help:thetraitIndex{integer}isnotimplementedforStringFormoreinformationaboutthiserror,tryrustcexplainE0277。error:couldnotcompilemyprojectduetopreviouserror 所以Rust字符串不支持索引语法访问。String类型的内部表示 String是对Vec的包装。String有一个len()方法,它返回的是String所占的字节数。例:fnmain(){letlenString::from(ypa)。len();println!({},len);letlenString::from()。len();println!({},len);} 以上代码输出3和6。因为字符串编码是UTF8,英文字母在UTF8占一个字节,所以ypa占3个字节。但是后面的并不是英文字母ypa,它是俄文,每个占2个字节,所以是6。注:常用汉字在UTF8编码下每个占3个字节。字节(Bytes)、标量值(ScalarValues)、字形簇(GraphemeClusters) Rust有三种看待字符串的方式:字节标量值字形簇(最接近字母的概念) 例:fnmain(){letwordString::from();forbyteinword。bytes(){以字节的形式表达字符串println!({},byte);}println!();forscalarinword。chars(){以Unicode标量值的形式表达字符串println!({},scalar);}} 因为字形簇处理起来比较复杂,所以Rust标准库没有提供返回字形簇的方法。可以借助Librarycrate来转换字符串为字形簇,例:首先在Cargo。toml添加依赖:〔package〕namemyprojectversion0。1。0edition2021〔dependencies〕unicodesegmentation1。8。0useunicodesegmentation::UnicodeSfnmain(){letwordString::from();forscalarinword。graphemes(true){以字形簇的形式表达字符串println!({},scalar);}} 由于以上三种形式,所以Rust不能用索引来访问String的部分数据。而Rust不允许对String使用索引还有另一个原因: 索引操作预期总是需要常数时间(O(1))。但是对于String不可能保证这样的性能,因为Rust必须从开头到索引位置遍历来确定有多少有效的字符。切割String 可以使用〔〕和一个范围来创建字符串切片,例如:fnmain(){letwordString::from();letsword〔0。。4〕;取前4个字节(左闭右开)println!({},s);因为此处是俄文,每个字母占2个字节,所以打印结果是letsword〔0。。3〕;取前3个字节println!({},s);编译通过但是运行时panic。threadmainpanickedatbyteindex3itisinside(bytes2。。4)of,srcmain。rs:8:14} 需要谨慎使用,因为如果切割时跨越了字符边界,程序运行时会panic,例如:假设某种文字,每个字符占2个字节,有此种语言的字符串(b1,b2)(b3,b4)(b5,b6),此时切割b1,b2,b3这三个字节,会导致b3跨越了第二个字符(b3,b4)而panic。遍历String的方法 在字节(Bytes)、标量值(ScalarValues)、字形簇(GraphemeClusters)里已经有了例子。对于标量值:chars()方法对于字节:bytes()方法对于字形簇:很复杂,标准库未提供,可借助第三方crateString不简单 Rust选择将正确处理String数据作为所有Rust程序的默认行为,程序员必须在处理UTF8数据之前投入更多精力。但是可以防止在开发后期处理设计非ASCII字符的错误。