一个可变引用的问题
从rust社区看到的一个问题,原文地址:https://users.rust-lang.org/t/calling-a-mu...
问题描述
题主实现如下代码,报错:
use std::collections::HashMap;
struct MyData {
d: f32
}
struct Foo {
d: HashMap<String, MyData>
}
impl Foo {
fn get(&mut self, s: &str) -> Option<&MyData> {
if !self.d.contains_key(s) {
self.d.insert(s.to_string(), MyData{ d: 0.0 });
}
self.d.get(s)
}
}
fn main() {
let mut foo = Foo {
d: HashMap::new()
};
let mut saved = Vec::new();
for _i in 1..3 {
let l = foo.get("a");
saved.push(l);
}
}
问题解决
方法一
use std::collections::HashMap;
#[derive(Clone, Copy)]
struct MyData {
d: f32
}
struct Foo {
d: HashMap<String, MyData>
}
impl Foo {
fn get(&mut self, s: &str) -> Option<MyData> {
if !self.d.contains_key(s) {
self.d.insert(s.to_string(), MyData{ d: 0.0 });
}
self.d.get(s).copied()
}
}
fn main() {
let mut foo = Foo {
d: HashMap::new()
};
let mut saved = Vec::new();
for _i in 1..3 {
let l = foo.get("a");
saved.push(l);
}
}
方法二
use std::collections::HashMap;
struct Foo {
d: HashMap<String, f32>
}
impl Foo {
fn get(&mut self, s: &str) -> Option<f32> {
if !self.d.contains_key(s) {
self.d.insert(s.to_string(), 0.0);
}
self.d.get(s).copied()
}
}
fn main() {
let mut foo = Foo {
d: HashMap::new()
};
let mut saved = Vec::new();
for _i in 1..3 {
let l = foo.get("a");
saved.push(l);
}
}
第一眼看到了下感觉没啥问题,执行了下确实报错了
自己理解的
主要是编译器的借用安全检查阻止,因为get方法返回的是对map中元素的一个引用,并且绑定到了Vec,编译器认为第二次对Foo的可变引用会造成内存的不安全,所以阻止