
在 Rust 里你几乎从不会写str却天天在写str。这本身就很奇怪如果str是字符串类型为什么用的时候总要加个那个省掉行不行str和str是同一个东西的两种写法还是两个不同的类型这篇就把这两个类型讲清楚。先看下面的代码fn main() { let a abc; let _: () a; // 编译错误会显示 a 的类型 }猜猜a是什么类型我这里故意让编译器报错来查看变量a的类型这种查看变量类型的方法虽然不太方便但是最准确。这里变量a的类型是str。当我一开始看到这个结果时是有一点懵逼的以为会是 str 类型。Rust 是这样描述 str 的str - RustThestrtype, also called a ‘string slice’, is the most primitive string type. It is usually seen in its borrowed form,str. It is also the type of string literals,static str.str类型也叫字符串切片是最基础的字符串类型。它通常以借用形式str出现。它也是字符串字面量的类型即static str。在Rust中str被设计成Dynamically Sized Type中文叫动态大小类型也常叫unsized type不定长类型意思是这个类型的大小在编译期无法确定只有运行时才知道。而Rust编译器在给变量分配栈空间时必须知道大小。我使用类型注解强制告诉编译器我要 str 类型看看会发生什么fn main() { let a:str abc; }编译结果很有意思编译器这里报了两个错。第一个错误提示不匹配的类型。abc 这里是一个表达式表达式计算得出的结果的类型是str而等号左侧是str类型导致类型不匹配第二个错误提示str 类型的值的大小在编译期间未知。注意这是两个不同的错误为什么 Rust 要把 str 设计成DST呢其实很好理解Rust 用 str 表示一段字符串这个类型但是这个字符串的长度是未知的比如 abc, abcd, 234%1, 这些字符串类型但它们的长度是不同的。而 str 是一个指针类型它的大小固定为16字节64 位平台。fn main() { let a abcd; let b abcde; println!(size_of::str() {} 字节, size_of::str()); }由两个字段组成ptr指向那段 UTF-8 字节的第一个字节len那段数据的字节数不是字符数那 str 类型的值在哪里怎么好像从来没见过字符串字面量abc指向的那段数据在程序加载时被放在静态区只读数据段这段数据的类型是str。而字面量表达式abc本身的类型是static str——它是指向那段数据的引用。也就是数据abc三个字节→ 类型str在静态区表达式abc→ 类型static str求值得到指向数据的引用变量a→ 类型str存这个引用16 字节在栈上用一张图总结下另外str 类型是Rust中的 primitive type, 也就是原生类型而 str 属于Rust 引用类型下的一个具体类型并且结构由编译器内部实现。