&str
简明指南
对于绝大对数读者来说,在 Rust 语言中想使用好 &str
类型并非易事。使用 &str
如同吃榴莲——“闻着臭,吃着香”。当然了吃相不好的话会被当成吃屎,这样做就得不偿失了。根据最近在推特上的一项调查当一个函数需要一个字符串的时候大约有73%的程序员会选择明确的 &str
或 String
类型,也就是说如果您只会用 Into<String>
看起来可不那么精明。当然这并不是说不能用 Into<String>
,在某些场景下这是好的。不过您不能只会这一种方法来处理字符串。那么这篇指南就带领您了解如何优雅的吃屎。诶,不对。是优雅的吃榴莲。诶,好像还不对。是优雅的使用 &str
类型。好了,这回对了。为了方便阐述这个问题我们假设我们有个字符串绑定到了标识符 chico
上,这里的 chico
译为“狗子”。
Chico 实际上是西语里面的小伙子的意思,这里“狗子”只是比较本土化的叫法
&str
类型放在什么位置
譬如说您一上来就让“狗子”绑定一句话,我们可以理解为狗子想说的话:
fn main() {
let chico = "我改不了吃屎";
println!("chico = {:?}", chico);
}
这里这句 "我改不了吃屎"
编译后会被写入二进制文件,也就是 'static
这个生命周期参数所表达的。如果我们不省略类型及生命周期的话,我们应该这样写:
fn main() {
let chico: &'static str = "我改不了吃屎";
println!("chico = {:?}", chico);
}
这时候您可能会有一个疑问了,那么如果所有的 &str
类型实际上都是被写入二进制文件的话,那么我还搞什么生命周期呢?因为显然不是这样的,并非所有的 &str
类型最终的归宿都是二进制文件。譬如说您从一个 String
里获得的:
fn chico_wants_to_say() -> String {
"我改不了吃屎".to_string()
}
fn main() {
let mut chico = "";
{
chico = &*chico_wants_to_say();
}
println!("chico = {:?}", chico);
}
您会发现这样一个程序就动不了。为什么呢,因为生命周期太短。到这里我们解答了 &str
类型的最典型的疑问,这个类型到底在哪儿?用双引号包裹的 &'static str
会被编译到二进制文件当中,如果您用过 wasm 会更清楚这一点。这种字符串会在程序运行时被加载到内容,除此之外的 &str
您不太需要了解它在内存中的位置。当然您如果想要专门探究这个问题可以通过 println!("{:p}", chico);
来进一步了解。这并不是这篇指南的重点,不再赘余。此外 &'static str
类型意味着这个字符串从程序开始到结束一直在内存中,也就是您一直可以访问到它,而不用担心作用域的问题。
String
和 &str
如何存在内存中
C 语言的字符串似乎让大家吃了不少亏。所以在 Rust 中的 String
和 &str
类型都不是以 0
结尾的。而是以字符串内容和字符串长度的形式存放在内存中的。显然可以通过字符串长度这个字段来控制字符串内容。也就不需要以 0
结尾了。您如果和 C 语言进行交互的时候还需要特别注意。如有需要请自行了解 FFI 相关内容。
评论区
写评论赞!不过臭豆腐在这更合适吧(榴莲闻不臭).
加了他的公众号了,但是,里面rust的文章很少啊
这种文章不错,希望以后多多发送,谢谢了!