为什么需要引用索引?
我目前正在从 JavaScript 学习 Rust。
我的问题如下:
fn main() {
let name = String::from("Tom");
let sliced = name[..2];
println!("{}, {}", name, sliced);
}
这不起作用。说"doesn't have a size known at compile-time"
。
为了解决这个问题,我需要添加&
引用运算符。
fn main() {
let name = String::from("Tom");
let sliced = &name[..2];
println!("{}, {}", name, sliced);
}
我知道我需要&
在 name 之前添加并且&
是引用运算符。但我只是不知道为什么我真的需要这样做?
通过引用变量,引用引用变量name
但不拥有它。如果我的引用超出范围,则不会删除原始值。这是否意味着如果我这样做了变量会超出范围name[...]
并且变量被删除并且因此我需要创建对它的引用来防止这种情况发生?
有人可以给我解释一下吗?
回答
我知道我需要
&
在 name 之前添加并且&
是引用运算符。但我只是不知道为什么我真的需要这样做。
我理解混乱的来源,因为当您查看index()
它时会返回&Self::Output
. 所以它已经返回了一个引用,这是怎么回事?
这是因为索引运算符是语法糖并使用Index
trait。然而,虽然它使用index()
which 确实返回了一个引用,但这并不是它的脱糖方式。
简而言之x[i]
,不是翻译为x.index(i)
,而是翻译为*x.index(i)
,因此引用立即取消引用。这就是你最终得到 astr
而不是 a 的方式&str
。
let foo = "foo bar"[..3]; // str
// same as
let foo = *"foo bar".index(..3); // str
这就是为什么您需要添加&
以使其“返回”到参考中。
let foo = "foo bar"[..3]; // str
// same as
let foo = *"foo bar".index(..3); // str
或者,如果您index()
直接调用,那么它当然不会隐式取消引用。
let foo = &"foo bar"[..3]; // &str
// same as
let foo = &*"foo bar".index(..3); // &str
特性std::ops::Index
- Rust 文档:
container[index]
实际上是语法糖*container.index(index)
这同样适用于IndexMut
.