为什么对 HashMap 建立索引不返回引用?

Joe*_*oey 3 indexing hashmap rust

我正在编写以下测试代码。

fn test() {
    let mut m = HashMap::new();
    m.insert("aaa".to_string(), "bbb".to_string());

    let a = m["aaa"];   // error [E0507] cannot move out of index of `HashMap<String, String>`
    let a  = m.index("aaa");  // ok, the type of a is &String. I think The compile will add & to m;
    let a :&String = (&m).index("aaa");  // ok, the type of a is &String.
    println!("{:?}", m["aaa"]);  // ok
}
Run Code Online (Sandbox Code Playgroud)

m["aaa"]我不明白为什么is的返回类型String, not &String。因为trait的index(&self, key: &Q) -> &VIndex有一个&self参数,所以我认为编译时会给&m加上a,而m["aaa"]的返回类型应该是&String,所以String "bbb"不会被移出m。

如果编译时没有在m中添加&,则不会找到index()方法,错误应该是这样的m cannot be indexed by "bbb"

Jmb*_*Jmb 13

文档中Index

\n
\n

container[index]实际上是语法糖*container.index(index)

\n
\n

因此,当您编写 时m["aaa"],编译器实际上会添加a*来取消引用 所返回的值Index::index,而当您调用 时m.index ("aaa"),您会&String直接获得引用。

\n

正如 @user4815162342 所指出的,程序员应该通过编写 或 来明确他们的&m["aaa"]意图m["aaa"].clone()

\n

此外,println!("{:?}", m["aaa"]);由于该println!宏确实将 a 添加&到它访问的所有值\xc2\xb9 中,以防止显示引起的意外移动,因此可以抵消*编译器添加的内容。

\n
\n

(1) 这间接记录在宏的文档中format_args!

\n

  • 可能还值得一提的是:1)编写作业的预期方式是 `let a = &amp;m["aaa"]` 或 `let a = m["aaa"].clone()`,具体取决于意图。2) `println!()` 之所以有效,是因为它会作弊并自动借用其参数来防止显示导致的移动。 (3认同)