Rust 如何使用不安全的代码对由RefCell/RwLock Ref/Guard封装的集合返回迭代器?

Rust 如何使用不安全的代码对由RefCell/RwLock Ref/Guard封装的集合返回迭代器?,rust,unsafe,Rust,Unsafe,关于此主题,已经提出了多个问题: 答案或多或少是:没有不安全因素是不可能的 我自己也试过这种不安全的方法,想问问这种方法是否安全 我的想法是将这个保护包封装在一个实现迭代器的结构中。除guard外,还存储了一个迭代器,该迭代器将从存储的guard创建: struct MapIter<'a> { guard: RwLockReadGuard<'a, HashMap<i32, i32>>, iter: Iter<'a, i32, i32&g

关于此主题,已经提出了多个问题:

答案或多或少是:没有不安全因素是不可能的

我自己也试过这种不安全的方法,想问问这种方法是否安全

我的想法是将这个保护包封装在一个实现迭代器的结构中。除guard外,还存储了一个迭代器,该迭代器将从存储的guard创建:

struct MapIter<'a> {
    guard: RwLockReadGuard<'a, HashMap<i32, i32>>,
    iter:  Iter<'a, i32, i32>,
}
这个密码安全吗

请在中查看此代码的作用

此外,我得到一个微不足道的演员警告

警告:普通强制转换:警告:普通强制转换:`&std::sync::RwLockReadGuard`。强制转换可以替换为强制转换,这可能需要类型归属或临时变量 |
|不安全{*&boxed.guard as*const RwLockReadGuard不安全。我可以使用容器在安全代码中创建悬挂引用:

let container = Container::new();       // create a container
let r = {
    let mut it = container.iter();
    it.next()                           // obtain a reference to part of it
};
container.map.write().unwrap().clear(); // empty the container
println!("{:?}", r);                    // oh dear.
在这种编译中,这是不好的,因为r包含对数据的引用,这些引用在清除HashMap时无效

更详细地解释了为什么这是不合理的,并包含以下简明摘要:

您不能这样做,因为这样可以避免运行时检查唯一性冲突


不,这不安全。我可以使用容器在安全代码中创建悬挂引用:

let container = Container::new();       // create a container
let r = {
    let mut it = container.iter();
    it.next()                           // obtain a reference to part of it
};
container.map.write().unwrap().clear(); // empty the container
println!("{:?}", r);                    // oh dear.
在这种编译中,这是不好的,因为r包含对数据的引用,这些引用在清除HashMap时无效

更详细地解释了为什么这是不合理的,并包含以下简明摘要:

您不能这样做,因为这样可以避免运行时检查唯一性冲突


假设您只返回值,即克隆项目,这是否安全?@Tim If next returned Option?我认为这是安全的,但我自己还没有完全相信。是的,这实际上是我的用例,但我删除它是为了制作一个。实际上,我有一个&u64,&DirEntry,它将转换为u64,PathBuf@Tim这是我所知道的到目前为止发现:通过类比,这似乎应该是安全的;但是,有一个与并发性的微妙交互,这相当于RwLockReadGuard的map。我不太了解这个问题,无法确定您建议的MapIter是否也不可靠。然而,您触发此sou的可能性似乎非常小ndness错误是偶然发生的。因此,如果它不太可能被触发,而你甚至不确定它是否存在,你可能会发现风险是可以接受的。我相信API可以安全地实现,因此即使实现错误,它也可以在将来得到修复。至少要保证iter在防范之前就被丢弃,以避免从这个角度出现问题。Assuming、 您只返回值,即克隆项目,这是否安全?@Tim如果下一个返回选项?我认为这是安全的,但我自己还没有完全相信。是的,这实际上是我的用例,但我删除它是为了制作一个。实际上,我有一个&u64,&DirEntry,它将转换为u64,PathBuf@Tim这是我发现的o far:通过类比,这似乎应该是安全的;但是,有一种与并发性的微妙交互,这相当于RwLockReadGuard的映射。我对这个问题的理解还不够透彻,无法确定您建议的映射器是否也不健全。然而,您触发这种健全性的可能性似乎非常小错误是偶然发生的。因此,如果它不太可能被触发,而你甚至不确定它是否存在,你可能会发现风险是可以接受的。我相信API可以安全地实现,所以即使实现错误,它也可以在将来得到修复。至少要保证iter在防范之前就被丢弃,以避免从这个角度出现问题。
let container = Container::new();       // create a container
let r = {
    let mut it = container.iter();
    it.next()                           // obtain a reference to part of it
};
container.map.write().unwrap().clear(); // empty the container
println!("{:?}", r);                    // oh dear.