如果我们有下面的代码:
struct Config {
username: Option<String>,
password: Option<String>,
}
fn some_fn(config: Config) {
let foo: &Option<String> = &config.username;
let bar: Option<&String> = config.username.as_ref();
let name1 = foo.unwrap(); // error
let name2 = bar.unwrap(); // no error
}
字符串
我有错误:
error[E0507]: cannot move out of `*foo` which is behind a shared reference
--> src\main.rs:9:17
|
9 | let name1 = foo.unwrap();
| ^^^^--------
| | |
| | `*foo` moved due to this method call
| help: consider calling `.as_ref()` or `.as_mut()` to borrow the type's contents
| move occurs because `*foo` has type `Option<String>`, which does not implement the `Copy` trait
|
note: `Option::<T>::unwrap` takes ownership of the receiver `self`, which moves `*foo`
型
我看了一下unwrap
方法,它是这样的:
pub const fn unwrap(self) -> T {
match self {
Some(val) => val,
None => panic("called `Option::unwrap()` on a `None` value"),
}
}
型
实际上,我不知道“共享引用后面有东西”到底是什么意思。乍一看,我在想,unwrap
需要一个self
参数,但foo
得到了一个&Option<String>
类型,它是一个引用,所以错误是有道理的。但是如果我把bar的类型改为引用,就像这样:
let bar: &Option<&String> = &config.username.as_ref();
let name2 = bar.unwrap(); // I thought this time there should be a error while still no error
型
所以回到问题上,关键的区别是&Option<String>
和&Option<&String>
之间,我只是不知道错误是什么意思,“*foo
由于这个方法调用而移动”,为什么*foo
不能移动到unwrap
?
这个问题的真正原因是什么?
1条答案
按热度按时间slhcrj9b1#
实际上,我不知道“共享引用后面有东西”到底是什么意思。
它位于
&
(共享引用)的内部/后面。乍一看,我在想,unwrap需要一个self参数,但是foo得到了一个&Option类型,它是一个引用,所以错误是有道理的。
这正是问题的根源。
unwrap
通过值获取Option
,你试图在引用上调用它,所以它试图在*foo
上调用方法(为了获得拥有的值),这是无效的:String
不是Copy
,所以Option<String>
也不是Copy
,因此*foo
需要移动值,并且不可能将值移出共享引用。第二种情况有效,因为
bar
是&Option<&T>
,引用总是Copy
,这也使得选项Copy
有效,所以*bar
有效。因此unwrap
编译得很好。您可以通过解引用来查看它,甚至不需要涉及
unwrap
:字符串