1.关于String的第一次记录
String、char、str的初步理解
字符串字面量如“hello”是&str类型,str是静态类型,String是堆上分配内存的可变类型,两者之间发生转换:
//从字面量&str hello转为String
let s = String::from("hello");
//取引用将String转为字面量(deref)
具体参考圣经:字符串与切片 - Rust语言圣经(Rust Course)
这里额外记录一点:String和&str都是UTF-8类型的,char在rust中默认为4字节(照顾UTF-32的unicode),在String中关于字符的操作,如push,是先将UTF-32转为UTF-8然后操作原String。
如String的追加操作,gpt说:
对于
push_str
方法,你传入的是一个字符串切片(&str
),这个切片会被附加到String
的末尾。由于String
是UTF-8编码的,所以追加的字符串也会按照UTF-8编码规则被追加到现有字符串的末尾。对于
push
方法,你传入的是一个char
字符。尽管在Rust中char
类型是使用UTF-32编码的,但在push
方法中,这个字符会被转换为UTF-8编码的字节序列,然后追加到String
的末尾。因此,无论字符在UTF-32中需要多少字节(总是4字节),在String
中它可能只占用一个或多个字节(取决于该字符在UTF-8中的编码)。
UTF-8:英文占一个字节,中文占三个字节
注意String的加法:
String + &str ,+调用add()方法,所有权会转移
fn main() {
let s1 = String::from("hello,");
let s2 = String::from("world!");
let s3 = s1 + &s2;
assert_eq!(s3,"hello,world!");
//println!("{}",s1);
2.关于循环和借用的第一次记录
学习泛型这一章节时遇到的代码问题(还存有困惑,后续深入再回头看看)
泛型 Generics - Rust语言圣经(Rust Course)
//先不论能不能跑这个泛型
//圣经
fn largest<T: std::cmp::PartialOrd>(list: &[T]) -> T {
let mut largest = list[0];
for &item in list.iter() {
if largest > item {
largest = item;
}
}
largest
}
//程序设计
fn largest<T: std::cmp::PartialOrd>(list: &[T]) -> &T {
let mut largest = &list[0];
for item in list {
if largest > item{
largest = item;
}
}
largest
}
程序设计的代码返回的是引用,可能出现悬空引用,先不管,只看函数。
这里有坑,一直没看懂“”rust程序设计“”的这段代码,以i32类型为例子,chatgpt是这样解释:
let mut largest = &list[0], largest是&i32类型,
for item in list {}这里item是i32类型,if判断时候,因为比较运算是值类型的比较,rust会对largest自动解引用,等价if *largest > item。
但总觉得怪怪的,这不如<圣经>的代码好理解,iter()返回list的借用迭代器,用&item代指切片借用,item就是值,然后比较。