【问题标题】:Why does indexing need to be referenced? [duplicate]为什么需要引用索引? [复制]
【发布时间】:2021-03-20 14:29:56
【问题描述】:

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

谁能解释一下?

【问题讨论】:

  • @mkrieger1 第二个作品。我只想知道& 到底做了什么让我的代码工作

标签: indexing rust slice


【解决方案1】:

我知道我需要在名称前添加&& 是引用运算符。但我只是不知道为什么我真的需要这样做。

我了解混乱的来源,因为当您查看 index() 时,它会返回 &Self::Output所以它已经返回了一个引用,这是怎么回事?


这是因为索引运算符是 语法糖 并使用 Index 特征。然而,虽然它使用了确实返回引用的index(),但它并不是这样去糖的。

总之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] 实际上是*container.index(index) 的语法糖

这同样适用于IndexMut

【讨论】:

  • 你能把我链接到index 方法吗?我在文档中找不到它。它在 rust 中被称为方法对吗?
  • 我已经链接了,点击答案中的任何index()。如果您对它的提及位置感到好奇,请查看文档顶部的 Index
  • 好的,谢谢,我会详细阅读。从 js 到 rust 就像跳入冷水。或冷冻水。不过谢谢你的解释
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多