Rust 与内部易变性作斗争
我的数据结构如下:Rust 与内部易变性作斗争,rust,borrow-checker,mutability,Rust,Borrow Checker,Mutability,我的数据结构如下: struct R { hmhs: HashMap<i64, HashSet<i64>>, } impl R { fn hs_for_hmhs(&mut self) -> &mut HashSet<i64> { if let None = self.hmhs.get(&0) { self.hmhs.insert(0, HashSet::new());
struct R {
hmhs: HashMap<i64, HashSet<i64>>,
}
impl R {
fn hs_for_hmhs(&mut self) -> &mut HashSet<i64> {
if let None = self.hmhs.get(&0) {
self.hmhs.insert(0, HashSet::new());
}
self.hmhs.get_mut(&0).unwrap()
}
fn iter_for_hmhs<'a>(&'a mut self) -> impl Iterator<Item = &'a i64> {
self.hs_for_hmhs().iter()
}
fn insert_for_hmhs(&mut self, i: i64) -> bool {
self.hs_for_hmhs().insert(i)
}
}
然而,我似乎总是遇到问题。主要是各种各样的
我在这里尝试了很多变体,但我遗漏了一些东西
我的理解是基本的。有没有一种方法可以实现我想要的
想要什么
:
使用std::cell::RefCell;
使用std::collections::{HashMap,HashSet};
结构R{
hmhs:HashMap,
}
impl R{
fn hs_for_hmhs(&mut self)->&mut HashSet{
如果let None=self.hmhs.get(&0){
self.hmhs.insert(0,HashSet::new());
}
self.hmhs.get_mut(&0).unwrap()
}
fn iter_for_hmhs impl Iterator我找到了一个解决方案——提取HashMap
作为原始指针。这反过来意味着我可以访问HashSet
,而无需使用包括返回迭代器在内的诡计
作为一个解决方案,我很高兴。不安全的代码很小并且包含在内,如果我理解编译器抱怨不安全的原因,它就不会出现在这段代码中,因为在构建之后,HashMap
和HashSet
都不会被删除或替换
这是很大的努力
use std::cell::RefCell;
use std::collections::{HashMap, HashSet};
struct R {
hmhs: HashMap<i64, HashSet<i64>>,
}
impl R {
fn hs_for_hmhs(&mut self) -> &mut HashSet<i64> {
if let None = self.hmhs.get(&0) {
self.hmhs.insert(0, HashSet::new());
}
self.hmhs.get_mut(&0).unwrap()
}
fn iter_for_hmhs<'a>(&'a mut self) -> impl Iterator<Item = &'a i64> {
self.hs_for_hmhs().iter()
}
fn insert_for_hmhs(&mut self, i: i64) -> bool {
self.hs_for_hmhs().insert(i)
}
}
struct S {
hmhs: RefCell<HashMap<i64, HashSet<i64>>>,
}
impl S {
fn hs_as_ptr(&self) -> *mut HashMap<i64, HashSet<i64>> {
self.hmhs.borrow_mut().entry(0).or_insert(HashSet::new());
self.hmhs.as_ptr()
}
fn mut_hs_for_hmhs(&mut self) -> &mut HashSet<i64> {
unsafe { (*self.hs_as_ptr()).get_mut(&0).unwrap() }
}
fn hs_for_hmhs(&self) -> &HashSet<i64> {
unsafe { (*self.hs_as_ptr()).get(&0).unwrap() }
}
fn iter_for_hmhs<'a>(&'a self) -> impl Iterator<Item = &'a i64> + 'a {
self.hs_for_hmhs().iter()
}
fn insert_for_hmhs(&mut self, i: i64) -> bool {
self.mut_hs_for_hmhs().insert(i)
}
}
fn main() {
let mut r = R {
hmhs: HashMap::new(),
};
let mut s = S {
hmhs: RefCell::new(HashMap::new()),
};
r.insert_for_hmhs(10);
s.insert_for_hmhs(20);
println!("r next: {:?}", r.iter_for_hmhs().next());
println!("s next: {:?}", s.iter_for_hmhs().next());
}
使用std::cell::RefCell;
使用std::collections::{HashMap,HashSet};
结构R{
hmhs:HashMap,
}
impl R{
fn hs_for_hmhs(&mut self)->&mut HashSet{
如果let None=self.hmhs.get(&0){
self.hmhs.insert(0,HashSet::new());
}
self.hmhs.get_mut(&0).unwrap()
}
fn iter_for_hmhs impl Iterator(&'a self)->impl Iterator bool{
self.mut_hs_for_hmhs().insert(i)
}
}
fn main(){
设mut r=r{
hmhs:HashMap::new(),
};
设mut s=s{
hmhs:RefCell::new(HashMap::new()),
};
r、 为_-hmhs(10)插入_;
s、 为_-hmhs插入_(20);
println!(“r next:{:?}”,r.iter_代表_hmhs().next());
println!((“s next:{:?}”,s.iter_代表_hmhs().next());
}
为什么需要可变地借用它?所有的方法都会返回对其内容的不可变引用?这是什么呢?HashMap
和第二个borrow\u mut
调用。我不知道。如果我不这样做,它会抱怨更多。啊,我没有注意到insert\u for_hmhs
调用insert
。哦,HashSet
--是的,这是一个问题part将实现结构的公共接口。HashMap实际上是一个实现细节。这是一个棘手的问题,我想知道您是否应该尝试另一种方法。例如,它将让您半途而废—一个指向HashSet
的抽象智能指针。但很难返回迭代器。
use std::cell::RefCell;
use std::collections::{HashMap, HashSet};
struct R {
hmhs: HashMap<i64, HashSet<i64>>,
}
impl R {
fn hs_for_hmhs(&mut self) -> &mut HashSet<i64> {
if let None = self.hmhs.get(&0) {
self.hmhs.insert(0, HashSet::new());
}
self.hmhs.get_mut(&0).unwrap()
}
fn iter_for_hmhs<'a>(&'a mut self) -> impl Iterator<Item = &'a i64> {
self.hs_for_hmhs().iter()
}
fn insert_for_hmhs(&mut self, i: i64) -> bool {
self.hs_for_hmhs().insert(i)
}
}
struct S {
hmhs: RefCell<HashMap<i64, HashSet<i64>>>,
}
impl S {
fn hs_for_hmhs(&self) -> &mut HashSet<i64> {
if let None = self.hmhs.borrow().get(&0) {
self.hmhs.borrow_mut().insert(0, HashSet::new());
}
self.hmhs.borrow_mut().get_mut(&0).unwrap()
}
fn iter_for_hmhs(&self) -> impl Iterator<Item = &i64> {
self.hs_for_hmhs().iter()
}
fn insert_for_hmhs(&self, i: i64) -> bool {
self.hs_for_hmhs().insert(i)
}
}
fn main() {}
use std::cell::RefCell;
use std::collections::{HashMap, HashSet};
struct R {
hmhs: HashMap<i64, HashSet<i64>>,
}
impl R {
fn hs_for_hmhs(&mut self) -> &mut HashSet<i64> {
if let None = self.hmhs.get(&0) {
self.hmhs.insert(0, HashSet::new());
}
self.hmhs.get_mut(&0).unwrap()
}
fn iter_for_hmhs<'a>(&'a mut self) -> impl Iterator<Item = &'a i64> {
self.hs_for_hmhs().iter()
}
fn insert_for_hmhs(&mut self, i: i64) -> bool {
self.hs_for_hmhs().insert(i)
}
}
struct S {
hmhs: RefCell<HashMap<i64, HashSet<i64>>>,
}
impl S {
fn hs_as_ptr(&self) -> *mut HashMap<i64, HashSet<i64>> {
self.hmhs.borrow_mut().entry(0).or_insert(HashSet::new());
self.hmhs.as_ptr()
}
fn mut_hs_for_hmhs(&mut self) -> &mut HashSet<i64> {
unsafe { (*self.hs_as_ptr()).get_mut(&0).unwrap() }
}
fn hs_for_hmhs(&self) -> &HashSet<i64> {
unsafe { (*self.hs_as_ptr()).get(&0).unwrap() }
}
fn iter_for_hmhs<'a>(&'a self) -> impl Iterator<Item = &'a i64> + 'a {
self.hs_for_hmhs().iter()
}
fn insert_for_hmhs(&mut self, i: i64) -> bool {
self.mut_hs_for_hmhs().insert(i)
}
}
fn main() {
let mut r = R {
hmhs: HashMap::new(),
};
let mut s = S {
hmhs: RefCell::new(HashMap::new()),
};
r.insert_for_hmhs(10);
s.insert_for_hmhs(20);
println!("r next: {:?}", r.iter_for_hmhs().next());
println!("s next: {:?}", s.iter_for_hmhs().next());
}