首页 > 解决方案 > 为什么 str 主要以借来的形式存在?

问题描述

这是该str类型的使用方式:

let hello = "Hello, world!";

// with an explicit type annotation
let hello: &'static str = "Hello, world!";

let hello: str = "Hello, world!";导致expected `str`, found `&str`

为什么文本的默认类型不仅str不同于所有原始类型、向量和String? 为什么是参考?

标签: stringtypesrustreferenceborrowing

解决方案


字符串和切片只能通过引用访问的设计决策有很多优点:

  1. 字符串可以有任意长度。因此,类型的变量str在堆栈上不容易管理,而&str只有堆栈上指针的大小(而可变长度数据驻留在堆上)。请注意,所有其他原始类型都有固定长度,每个引用都有固定长度(不是它指向的数据)和每个结构(这是一个组合)。
  2. &str是一个不可变的引用。如果您可以定义类型的变量,str则必须为let mut s: str = "str";. 堆栈上的不可变字符串很难管理,可以附加的字符串更难。
  3. 拥有str意味着每一步都必须复制所有字符,这会降低性能。只是复制引用并在堆上保持引用数据不变更便宜。这并不是真正的零成本抽象。
  4. str不是唯一仅作为参考出现的类型&str(对于切片同样适用,例如&[i8]),因此对字符串处理的更改会使其他行为变得奇怪(或者必须相应地更改)。
  5. 让我们假设一个函数可以管理 type 的变量str。现在你想&str从这个函数中返回一个。这是行不通的,因为引用最多只存在于它指向的值(尝试使用任何原始类型)。由于str是本地创建的值,因此它不能超过功能。字符串文字始终是对静态字符串的引用的便利解决了这个问题。这意味着您必须编写额外的代码来将您拥有str的变量放入静态变量中,这样您就可以返回&str. 由于静态引用是我需要的默认行为,因此我可以用很少的开销编写它非常方便。

推荐阅读