我有一个特性,具有以下功能:
pub trait MappedMemory {
fn range(&self) -> MappedMemoryRange;
fn flush(&mut self);
fn flush_range(&mut self, range: MappedMemoryRange);
fn flush_ranges(&mut self, ranges: &[MappedMemoryRange]);
fn flush_multiple(memories: &[&mut Self]);
fn flush_multiple_ranges(memories: &[(&mut Self, MappedMemoryRange)]);
}
pub struct MappedMemoryRange {
pub offset: u64,
pub size: usize
}
字符串
我试图为flush_multiple
提供一个调用flush_multiple_ranges
的默认实现。
我尝试了这样的方法将&[&mut Self]
转换为&[(&mut Self, MappedMemoryRange)]
:
let memories_and_ranges: Vec<(&mut Self, MappedMemoryRange)> = memories
.into_iter()
.map(|m| (*m, m.range()))
.collect();
型
这给了我错误:
error[E0507]: cannot move out of `*m` which is behind a shared reference
--> crates\xyz\src\objects\memory.rs:44:23
|
44 | .map(|m| (*m, m.range()))
| ^^ move occurs because `*m` has type `&mut Self`, which does not implement the `Copy` trait
型
我怎样才能让rust相信我只是在沿着这些引用,就像我只有一个引用一样?
2条答案
按热度按时间iugsix8n1#
不能在不可变引用后面改变可变引用。函数签名必须是:
字符串
它可以像这样实现:
型
我交换了顺序(先
MappedMemoryRange
),因为在前一个顺序中,你借用m
来交换m.range()
,而它已经是可变借用的。但是,我不清楚为什么不直接在每个内存上调用
flush()
,而不计算它的范围。58wvjzkj2#
我的问题中有一个根本的误解,就是:
&mut T
并不表示可变引用,更重要的是,&T
并不表示不可变引用。相反,&mut T
是唯一引用,而&T
是共享引用。&T
仍然可以是使用内部可变性可变的。在这个特定的例子中,我应该使用
&[&Self]
,因为引用需要共享。只要刷新调用在返回之前释放可变内部,一切都应该是好的。而且,MappedMemory
不是Sync
,因此我也不需要考虑并发访问。显然,在铁 rust 的早期有一个很大的讨论,关于
mut
被称为mut
,而不是像uniq
的东西,这是“mutpocalypse”的一部分。可悲的是,没有什么结果,因为我肯定有错误的理解了很长一段时间。