rust - 使用 transmute 实现可变迭代器以避免与不可变对应物的代码重复是否安全?
问题描述
Vec
我有一个自定义迭代器,它以非连续方式从对 a 的引用中读取数据。它永远不会返回对同一内存的两个引用,所以我相信实现一个可变的对应物是安全的。
然而,迭代器本身的逻辑是相当复杂的,对于可变版本来说它是完全一样的。为了避免代码重复,我在底层使用我的非 mut 迭代器,然后转换结果以增加可变性。这按预期工作,但我不确定它是否在调用某种未定义的行为。
pub mod lib {
pub struct Data {
pub v: Vec<u64>,
}
impl Data {
pub fn iter(&self) -> MyIter {
MyIter {
data: &self.v,
i: 0,
}
}
pub fn iter_mut(&mut self) -> MyIterMut {
MyIterMut { iter: self.iter() }
}
}
pub struct MyIter<'a> {
data: &'a [u64],
i: usize,
}
impl<'a> Iterator for MyIter<'a> {
type Item = &'a u64;
fn next(&mut self) -> Option<Self::Item> {
if self.i == self.data.len() {
return None;
}
let res = &self.data[self.i];
self.i += 1;
Some(res)
}
}
pub struct MyIterMut<'a> {
iter: MyIter<'a>,
}
impl<'a> Iterator for MyIterMut<'a> {
type Item = &'a mut u64;
fn next(&mut self) -> Option<Self::Item> {
unsafe { std::mem::transmute(self.iter.next()) }
}
}
}
fn main() {
let mut d = lib::Data { v: vec![0; 8] };
for elem in d.iter_mut() {
*elem = 123;
}
println!("{:?}", d.v);
}
可变迭代器仅在iter_mut
方法中构造。这意味着初始值将始终作为可变变量开始,因为&mut self
. 不可能从不可变变量构造这个可变迭代器。
在 C++ 中,您通常会使用 aconst_cast
来避免重复仅在 constness 上有所不同的实现。
这是我可以在 Rust 中做的事情吗?
解决方案
如果MyIter
包含对原始 vec 的不可变引用,则不能转换,因为您可能有多个 的实例MyIter
,从而导致引用冲突。似乎duplicate
crate 可以在这里使用,它提供了一种复制代码的简单方法,但略有不同。
推荐阅读
- node.js - 错误 /vercel/path0/node_modules/mozjpeg:命令失败。Next.js 应用程序
- algorithm - 使用 DP 找到在 NxM 棋盘上安排任意数量的骑士的多种方法?
- python - 如何制作一个在句子开头大写单词的函数
- verilog - 数组乘法与输入的综合误差
- powerbi - PowerBI:显示所有轴值,与所选内容无关
- java - 用于 Java 的 IntSet 的 toString
- java - 从 gradle api 插件中检索依赖 jar 文件
- python - 如何将一个表中的几列的行插入另一个表并传递其他几列的默认值?
- c - Linux 设备驱动程序在链接时的参数
- mysql - 从 MySQL 中的逗号分隔字段中删除重复项和计数