我想把SomeType从Result<Vec<Data<&SomeType>>>中拿出来,然后通过一个通道传递它,但是我失败了:
pub fn read(result: Result<Vec<Data<&SomeType>>, ()>, tx: mpsc::Sender<SomeType>) {
if let Ok(datas) = result {
for data in datas.iter() {
let actual_data = data.value();
let some_type_instance = SomeType { k: 1 };
tx.send(some_type_instance); // works
tx.send(**actual_data); // errors
}
}
}错误有:
error[E0507]: cannot move out of `**actual_data` which is behind a shared reference
--> src/main.rs:40:21
|
40 | tx.send(**actual_data);
| ^^^^^^^^^^^^^ move occurs because `**actual_data` has type `SomeType`, which does not implement the `Copy` traittx似乎没有正确地对待所有权。虽然在Copy上实现SomeType特性可以消除错误,但我不确定Copy或Clone是否会降低性能。我正在挣扎,但找不到一个正确的方法来解决它。
以下是重新生成错误的完整代码.
use std::result::Result;
use std::sync::mpsc;
pub struct SomeType {
k: i32,
}
pub struct Data<D> {
value: D,
}
impl<D> Data<D> {
pub fn value(&self) -> &D {
&self.value
}
}
pub fn main() {
let a = SomeType { k: 1 };
let b = SomeType { k: 2 };
let c = SomeType { k: 3 };
let A = Data { value: &a };
let B = Data { value: &b };
let C = Data { value: &c };
let datas = vec![A, B, C];
let result = Ok(datas);
let (tx, rx) = mpsc::channel();
read(result, tx);
}
pub fn read(result: Result<Vec<Data<&SomeType>>, ()>, tx: mpsc::Sender<SomeType>) {
if let Ok(datas) = result {
for data in datas.iter() {
let actual_data = data.value();
let some_type_instance = SomeType { k: 1 };
tx.send(some_type_instance); // this line works
tx.send(**actual_data); // this line errors
}
}
}发布于 2021-09-24 20:19:58
当您只有一个&T时,如果不克隆引用后面的值,就无法得到一个T,因为提取一个非复制值会移动它,而发出引用的T (此处为Data)的所有者希望该值仍然有效。
但是,如果控制存储到Data中的类型,则可以将实际值包装在Option中。然后,可以使用std::mem::replace(ref_to_t, None)获取引用后面的值,并将None保留在它的位置上。Option甚至有一个take()方法可以为您完成这个任务。
但是mem::replace()和Option::take()都需要一个可变的引用,而您所拥有的只是一个共享的引用。要解决这个问题,您还需要使用内部可更改性,如RefCell提供的。然后您将放入Data中的类型是RefCell<Option<SomeType>> --不要被嵌套的泛型所延迟,只需将它们读为“包含可选SomeType的RefCell”)。RefCell有一个borrow_mut()方法,为您提供了对内部内容的可变引用,然后您可以在该方法上调用Option::take(),或者您可以调用RefCell::take(),它将自己做正确的事情。
pub fn main() {
let a = SomeType { k: 1 };
let b = SomeType { k: 2 };
let c = SomeType { k: 3 };
let da = Data {
value: RefCell::new(Some(a)),
};
let db = Data {
value: RefCell::new(Some(b)),
};
let dc = Data {
value: RefCell::new(Some(c)),
};
let datas = vec![da, db, dc];
let (tx, _rx) = mpsc::channel();
read(&datas, tx);
}
pub fn read(datas: &[Data<RefCell<Option<SomeType>>>], tx: mpsc::Sender<SomeType>) {
for data in datas {
let actual_data = data.value().take().unwrap();
tx.send(actual_data).unwrap();
}
}https://stackoverflow.com/questions/69244550
复制相似问题