为什么不使用 Option unwrap 移动值?
Why the value is not moved with Option unwrap?
这里是 Rust 的新手,正在尝试学习。考虑以下代码:
let x = Some("air");
println!("{}", x.unwrap());
println!("{}", x.unwrap());
为什么这行得通?因为 unwrap
方法有下面的签名 pub fn unwrap(self) -> T
,所以它应该把 self
移到方法中,这意味着在第一次调用 x.unwrap
之后,我不应该能够访问 x
了。然而,这仍然有效吗?有人可以解释一下我在这里的误解吗?
unwrap()
方法用于从被选元素中移除父元素,而不是元素本身。
假设 Y
是 'X' 的父级,'Z' 是 'Y' 的父级,那么当你说 x.unwrap()
X 的父级时 'Y'被删除并且 'Z' 成为 'X' 的父级,现在当您再次说 x.unwrap()
时 'Z' 被删除。
刚刚发现,OP中的x
没有被移动,因为Option<&str>
实现了Copy
特征。另一方面,如果选项中的内部类型是更复杂的类型,例如 struct
,这将不起作用:
struct Node<T> { elem: T }
let y = Some(Node { elem: 3});
println!("{}", y.unwrap().elem);
println!("{}", y.unwrap().elem);
会报如下错误:
Line 33, Char 24: use of moved value: `y` (solution.rs)
|
32 | println!("{}", y.unwrap().elem);
| - value moved here
33 | println!("{}", y.unwrap().elem);
| ^ value used here after move
|
您将 &str
与 String
混淆了,而 Copy
并非如此。
fn main() {
// This will work fine.
let x = Some("data");
println!("{:?}", x.unwrap());
println!("{:?}", x.unwrap());
// however, this will generate an error since value will be moved.
let x = Some("data".to_string());
println!("{:?}", x.unwrap());
println!("{:?}", x.unwrap());
}
这里是 Rust 的新手,正在尝试学习。考虑以下代码:
let x = Some("air");
println!("{}", x.unwrap());
println!("{}", x.unwrap());
为什么这行得通?因为 unwrap
方法有下面的签名 pub fn unwrap(self) -> T
,所以它应该把 self
移到方法中,这意味着在第一次调用 x.unwrap
之后,我不应该能够访问 x
了。然而,这仍然有效吗?有人可以解释一下我在这里的误解吗?
unwrap()
方法用于从被选元素中移除父元素,而不是元素本身。
假设 Y
是 'X' 的父级,'Z' 是 'Y' 的父级,那么当你说 x.unwrap()
X 的父级时 'Y'被删除并且 'Z' 成为 'X' 的父级,现在当您再次说 x.unwrap()
时 'Z' 被删除。
刚刚发现,OP中的x
没有被移动,因为Option<&str>
实现了Copy
特征。另一方面,如果选项中的内部类型是更复杂的类型,例如 struct
,这将不起作用:
struct Node<T> { elem: T }
let y = Some(Node { elem: 3});
println!("{}", y.unwrap().elem);
println!("{}", y.unwrap().elem);
会报如下错误:
Line 33, Char 24: use of moved value: `y` (solution.rs) | 32 | println!("{}", y.unwrap().elem); | - value moved here 33 | println!("{}", y.unwrap().elem); | ^ value used here after move |
您将 &str
与 String
混淆了,而 Copy
并非如此。
fn main() {
// This will work fine.
let x = Some("data");
println!("{:?}", x.unwrap());
println!("{:?}", x.unwrap());
// however, this will generate an error since value will be moved.
let x = Some("data".to_string());
println!("{:?}", x.unwrap());
println!("{:?}", x.unwrap());
}