gpt4 book ai didi

rust - 如何重新使用已将值移出的盒子?

转载 作者:行者123 更新时间:2023-11-29 07:44:20 25 4
gpt4 key购买 nike

我有一些不可复制的类型和一个使用并(可能)生成它的函数:

type Foo = Vec<u8>;

fn quux(_: Foo) -> Option<Foo> {
Some(Vec::new())
}

现在考虑一种在概念上与 Box 非常相似的类型:

struct NotBox<T> {
contents: T
}

我们可以编写一个函数,临时移出 NotBox 的内容,并在返回之前将内容放回原处:

fn bar(mut notbox: NotBox<Foo>) -> Option<NotBox<Foo>> {
let foo = notbox.contents; // now `notbox` is "empty"
match quux(foo) {
Some(new_foo) => {
notbox.contents = new_foo; // we put something back in
Some(notbox)
}
None => None
}
}

我想编写一个与 Boxes 一起工作的类似函数,但编译器不喜欢它:

fn baz(mut abox: Box<Foo>) -> Option<Box<Foo>> {
let foo = *abox; // now `abox` is "empty"
match quux(foo) {
Some(new_foo) => {
*abox = new_foo; // error: use of moved value: `abox`
Some(abox)
}
None => None
}
}

我可以返回 Some(Box::new(new_foo)) 而不是执行不必要的分配 - 我已经有一些内存可供使用!有没有可能避免这种情况?

我也想去掉 match 语句,但编译器还是不满意(即使是 NotBox 版本):

fn bar(mut notbox: NotBox<Foo>) -> Option<NotBox<Foo>> {
let foo = notbox.contents;
quux(foo).map(|new_foo| {
notbox.contents = new_foo; // error: capture of partially moved value: `notbox`
notbox
})
}

有没有可能解决这个问题?

最佳答案

所以,从 Box 中移出是一种特殊情况……现在怎么办?

std::mem 模块提供了许多安全函数来 move 值,而不会在 Rust 的内存安全中戳洞(!)。这里感兴趣的是 swapreplace :

pub fn replace<T>(dest: &mut T, src: T) -> T

我们可以这样使用:

fn baz(mut abox: Box<Foo>) -> Option<Box<Foo>> {
let foo = std::mem::replace(&mut *abox, Foo::default());

match quux(foo) {
Some(new_foo) => {
*abox = new_foo;
Some(abox)
}
None => None
}
}

它在 map 情况下也有帮助,因为它没有借用 Box:

fn baz(mut abox: Box<Foo>) -> Option<Box<Foo>> {
let foo = std::mem::replace(&mut *abox, Foo::default());

quux(foo).map(|new_foo| { *abox = new_foo; abox })
}

关于rust - 如何重新使用已将值移出的盒子?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38397163/

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