rust - 使用 transmute 实现可变迭代器以避免与不可变对应物的代码重复是否安全?

标签 rust iterator

这个问题在这里已经有了答案:





Is there a way to make an immutable reference mutable?

(2 个回答)



Why is transmuting &T to &mut T Undefined Behaviour?

(2 个回答)



How to avoid writing duplicate accessor functions for mutable and immutable references in Rust?

(4 个回答)


1年前关闭。




我有一个自定义迭代器,它从对 Vec 的引用中读取数据以非连续方式。它永远不会返回对同一内存的两个引用,所以我相信实现一个可变的对应物是安全的。
然而,迭代器本身的逻辑是相当复杂的,对于可变版本来说它是完全一样的。为了避免代码重复,我在底层使用我的非 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);
}
Complete working example
可变迭代器仅在 iter_mut 中构造。方法。这意味着由于&mut self,初始值将始终作为可变变量开始。 .不可能从不可变变量构造这个可变迭代器。
在 C++ 中,您经常会使用 const_cast避免重复仅在 constness 上有所不同的实现。
这是我可以在 Rust 中做的事情吗?

最佳答案

如果 MyIter包含对原始 vec 的不可变引用,则无法转换,因为您可能有多个 MyIter 实例,导致引用冲突。好像是 duplicate crate 可以在这里使用,它提供了一种复制代码的简单方法,但略有不同。

关于rust - 使用 transmute 实现可变迭代器以避免与不可变对应物的代码重复是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64840552/

相关文章:

STL 容器上的 C++ 模板函数

rust - 如何克隆包含盒装特征对象的 HashMap?

rust - 如何根据 Rust 中的编译标志制作类型别名?

algorithm - 从 Vec<String> 构建 UrlTree

python - 清理 for 循环中断

Python itertools 创建随机子集的迭代器

asynchronous - Rust中异步/等待的目的是什么?

Rust Amethyst Pong 教程示例给出 "error: no example target named ` pong_tutorial_0 1`"

c++ - 没有 edge_predicate 的 BOOST filtered_graph 中的 out_edges() 实现

C++ 成员引用基类型 'Vertex *const' 不是结构或 union