gpt4 book ai didi

rust - 在将它们传递给函数后尝试使用它们时,不可复制的拥有值的生命周期问题

转载 作者:行者123 更新时间:2023-11-29 08:06:13 25 4
gpt4 key购买 nike

我在 Rust 中遇到了一些关于变量生命周期的问题。 do_stuff 中的 x 变量被借用给 try_wrap,因此在 None 情况下无法返回。我是不是想错了?

struct NonCopyable;

impl NonCopyable {
fn new() -> Self {
NonCopyable
}
}

fn do_stuff() -> NonCopyable {
let x = NonCopyable::new();
match try_wrap(x) {
Some(val) => val,
None => x,
}
}

fn try_wrap(x: NonCopyable) -> Option<NonCopyable> {
None
}

fn main() {}
error[E0382]: use of moved value: `x`
--> src/main.rs:13:17
|
11 | match try_wrap(x) {
| - value moved here
12 | Some(val) => val,
13 | None => x,
| ^ value used here after move
|
= note: move occurs because `x` has type `NonCopyable`, which does not implement the `Copy` trait

最佳答案

with lifetime of variables

这里不涉及生命周期

The x variable in do_stuff is borrowed

不,不是。

Am I thinking about this the wrong way?

是的。借用由符号 & 和/或生命周期参数 'foo 表示:

&i32    // a borrowed integer
&'a str // a borrowed string slice with a lifetime
Foo<'b> // a type that contains a borrow of some kind

您的 try_wrap 函数取得 x 的所有权:

fn try_wrap(x: NonCopyable) -> Option<NonCopyable>

这意味着 x 已经消失,调用函数无法再访问它。它已被移动try_wrap 中,它现在可以自由地对该值做任何它想做的事情,包括销毁它。这就是调用函数不再能够安全访问它以及出现错误的原因。

如果类型实现了Copy,编译器会隐式创建值的副本并将其传入。如果类型实现了Clone,您可以显式在 try_wrap 的参数上调用了 .clone() 以保留本地值。

作为Florian Weimer注意,您可以使用类型返回包装后的值或原始值。根据您的示例很难判断,但我不同意使用 Result 除非它是一个错误。相反,我会创建自己的一次性枚举或使用类似 Either 的东西:

extern crate either;

use either::Either;

fn do_stuff() -> NonCopyable {
let x = NonCopyable::new();
match try_wrap(x) {
Either::Left(val) => val,
Either::Right(x) => x,
}
}

fn try_wrap(x: NonCopyable) -> Either<NonCopyable, NonCopyable> {
Either::Right(x)
}

您还可以将 try_wrap 的逻辑嵌入到 do_stuff 中,或者拆分 try_wrap 以便逻辑不需要所有权:

fn do_stuff() -> NonCopyable {
let x = NonCopyable::new();
if should_wrap(&x) { do_wrap(x) } else { x }
}

fn should_wrap(x: &NonCopyable) -> bool { false }
fn do_wrap(x: NonCopyable) -> NonCopyable { x }

由于您要返回相同的类型,因此您也可能想要对该值进行可变引用,并只执行需要发生的任何条件更改:

fn do_stuff() -> NonCopyable {
let mut x = NonCopyable::new();
try_wrap(&mut x);
x
}

fn try_wrap(x: &mut NonCopyable) {}

关于rust - 在将它们传递给函数后尝试使用它们时,不可复制的拥有值的生命周期问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45255478/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com