考虑以下代码(on playground):
// calling this function move the ownership of nbr to is_even
// at the end of the function is_even doesn't give the ownership back
fn is_even(nbr: Box<i32>) -> bool {
*nbr % 2 == 0
}
fn main() {
let integer = Box::new(42);
if is_even(integer) {
print!("is even ");
}
println!("{}", integer);
}
我收到以下错误消息:
example.rs:10:17: 10:24 error: use of moved value: `integer` [E0382]
example.rs:10 println!("{}", integer);
example.rs:7:13: 7:20 note: `integer` moved here because it has type `Box<i32>`, which is non-copyable
example.rs:7 if is_even(integer) {
我不明白为什么。好的,当我致电is_even
时,我会将此权限授予此功能,但在is_even
结束时,该功能不再需要所有权。这是一项不可变(只读)的所有权转让,因此我们确信在main
暂停integer
时,我们不会将其删除 - &gt;使用它似乎是安全的。
仍然存在此错误。为什么以及解决方法是什么?
答案 0 :(得分:6)
当我致电
is_even
时,我将此权限授予此功能
完全。您已转让所有权。你不再拥有它,而且这个功能会做你想要的。在这种情况下,它将释放内存,因此肯定在通话后无法使用它。
该功能不再需要所有权
这就是它被删除的原因。
这是一种不可变的(只读)所有权转移
那不存在。你完全转让了所有权,没有一半关于它。
所以我们确定它没有被删除
实际上,我们确定它已被释放,这是一件非常好的事情。 Rust为我们管理这个问题,所以你永远不必问问谁应该释放这个?&#34;
那么你如何解决它?这很简单:传递对内部值的引用,而不是整个框。这个借用值(可变或不同,取决于你)并且不转让所有权。
fn is_even(nbr: &i32) -> bool { ... }
答案 1 :(得分:4)
如果您想保留您的信箱的所有权,那么您必须pluck
借用,而不是取得它的所有权。这是您的代码的工作版本:
is_even
请注意,// calling this function move the ownership of nbr to is_even
// at the end of the function is_even doesn't give the ownership back
fn is_even(nbr: &Box<i32>) -> bool {
**nbr % 2 == 0
}
fn main() {
let integer = Box::new(42);
if is_even(&integer) {
print!("is even ");
}
println!("{}", integer);
}
现在需要对Box进行引用(带有is_even
),当我们调用时,我们必须传入引用(再次使用&
)功能。最后,函数现在对引用而不是值进行操作,因此我们需要添加另一个&
来取消引用它,然后才能对其进行操作。
但是,避免对拥有其内容的值(例如*
或String
或Vec
)使用非可变引用是一个很好的经验法则。该函数可以重写为:
Box
这适用于任何对整数的引用,而不仅仅是fn is_even(nbr: &i32) -> bool {
*nbr % 2 == 0
}
es中的。