为什么索引HashMap不返回引用?



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

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
}

我不明白为什么m["aaa"]的返回类型是String,而不是&String。因为索引(&self, key: &Q) ->特性Index的V有一个&self参数,我认为编译会给m添加一个&, m["aaa"]的返回类型应该是&String,所以String "bbb"不会被移出m.

如果编译没有添加&对于m,它不会找到index()方法,错误应该像m cannot be indexed by "bbb";

From docs forIndex:

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

所以当你写m["aaa"]时,编译器实际上是添加了一个*来解引用Index::index返回的值,而当你调用m.index ("aaa")时,你直接得到&String引用。

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

此外,println!("{:?}", m["aaa"]);可以工作,因为println!宏确实为它访问的所有值添加了一个&,以防止由于显示而导致的意外移动,这抵消了编译器添加的*


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

最新更新