我不明白为什么以下操作无效:
use std::collections::HashMap;
#[derive(Debug,Clone,PartialEq)]
struct Foo<'a> {
contents: HashMap<&'a str, Foo<'a>>,
}
fn bar<'a>(val: Foo<'a>) -> Foo<'a> {
*val.contents.get("bar").clone().unwrap()
}
error[E0507]: cannot move out of a shared reference
--> src/lib.rs:9:5
|
9 | *val.contents.get("bar").clone().unwrap()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ move occurs because value has type `Foo<'_>`, which does not implement the `Copy` trait
我正在执行.clone()
,我认为应该允许我返回结果值,该结果的所有权应与输入值分离,但事实并非如此。
另一不可思议的事情,它本身并不是一个阻止程序,但可能暗示了潜在的问题,是由于某种原因,.clone()
返回了一个&Foo
,这令人惊讶,因为在其他情况下我主要看到.clone()
来自&T -> T
。这就是*
在这里的原因;没有它,这将无法通过类型检查。我知道Rust有一些“神奇的”引用/取消引用规则,但是我不太清楚这一点。
答案 0 :(得分:1)
HashMap.get
返回一个Option<&T>
。克隆此选项将为您提供另一个Option<&T>
,引用同一对象。
如果要将Option<&T>
转换为Option<T>
支持T
的新Clone
,则可以使用.cloned()
。由于您拥有T
而不是&T
,因此也不再需要取消引用。
这意味着您的代码将类似于this:
use std::collections::HashMap;
#[derive(Debug, Clone, PartialEq)]
struct Foo<'a> {
contents: HashMap<&'a str, Foo<'a>>,
}
fn bar<'a>(val: Foo<'a>) -> Foo<'a> {
val.contents.get("bar").cloned().unwrap()
}