为什么需要引用索引?

Why does indexing need to be referenced?

我目前正在学习来自 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[...] 并且变量被删除,变量将超出范围,因此我需要创建对它的引用以防止这种情况发生?

有人能给我解释一下吗?

I know I need to add & before name and & is the referencing operator. But I just don't know why I actually need to do that.

我明白混乱从何而来,因为当您查看 index() 时,它 return 就是 &Self::Output所以它已经 return 是一个参考,这是怎么回事?


因为索引运算符是语法糖,使用了Index trait。然而,虽然它使用 index() 做 return 一个参考,但它不是如何脱糖的。

简而言之x[i]不是翻译成x.index(i),而是实际翻译成 *x.index(i),所以引用立即被取消引用。 这就是您最终得到 str 而不是 &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(),那么它当然不会被隐式取消引用。

use std::ops::Index;

let foo = "foo bar".index(..3); // &str

Trait std::ops::Index - Rust Documentation:

container[index] is actually syntactic sugar for *container.index(index)

同理IndexMut.