У меня есть какой-то некопируемый тип и функция, которая его потребляет и (возможно) производит:
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
}
}
Я хочу написать аналогичную функцию, работающую с Box
es, но компилятору это не нравится:
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<T>
; похоже, это не связано с чертамиDeref
илиDerefMut
. Так что тоже жду хорошего ответа! - person Chris Emerson   schedule 15.07.2016