str与String之间的区别
String是在heap上动态分配的字符串类型,类似 Vec;使用场景:当你需要拥有或修改字符串数据时。
str 是 UTF-8字节的不可变序列,内存中长度可变。因为str的大小是未知的,你只能通过指针来操作str。这意味着str通常以&str
出现:表示指向UTF-8数据的引用;通常也称为string slice
或者仅仅是slice
。slice
仅仅是一些数据的视图,这些数据可以出现在任意地方。
- 在静态存储中:字符串是
&'static str
。数据被硬编码到可执行文件中,当程序运行时加载到内存中。 - 在heap上分配的String:String指
String数据的 &str view的去引用
。 - 在stack上:可以创建在stack分配的字节数组,然后获取数据的view作为
&str
use std::str; #[test] fn test_stack_allocated_str() { let x: &[u8] = &[b'a', b'b', b'c']; let stack_str: &str = str::from_utf8(x).unwrap(); println!("stacked_str: {}", stack_str); }
总结:如果你需要拥有字符串的所有权(比如传递string到其他线程中,或者在运行时构建string),可以使用String。如果你需要一个字符串的引用,可以使用&str
。
这类似于Vec<T>
和切片&[T]
之间的关系,也类似于 基本类型的值T
和&T
的引用之间的关系。
self与Self之间的区别
方法参数中的Self
是一种语法糖,表示方法的接收者类型。
Self
可能出现在trait
或者impl
,但是更多出现在trait
,它是最终实现trait
的任何类型的占位符(类型在定义trait
是未知的)
pub strait Clone {
fn clone(&self) -> Self
}
&self
是trait
或者impl
中某个方法的第一个参数。也可以使用其他命名,然而,这里有明显不同:
- 如果使用
self
,实现的函数是一个方法 - 如果使用其他命名,实现的函数是一个关联函数
当self
作为方法的第一个参数时,是self: Self
的简写。类似,&self
等价于self: &Self
;&mut self
等价于self: &mut Self