我是一个生锈的初学者,并尝试使用HashMap
let mut r = HashMap::new();
let mut i = 2;
...
if r.contains_key(&i) {
let v = r.get(&i).unwrap();
r.remove(&i);
r.insert(i, v+1);
}
现在,借用检查器抱怨说,
r
在if
-块的三行中是借用不可变的,然后是可变的,然后又是不可变的。我不明白发生了什么。。。我想既然get
、remove
和insert
方法都有r
作为隐式参数,那么这三个调用都借用了它。但是为什么remove
调用中的借用是可变的呢?
问题是,在获取v
时,您会保留一个不可变的引用。由于它是一个u64,只需隐式地克隆
,因此不需要更多的引用:
let v = r.get(&i).unwrap().clone();
游戏场
但是为什么在删除调用中的这个借是可变的呢?
问题是跨越:Rust允许任意数量的不可变借入或单个可变借入,它们不能重叠。
这里的问题是v
是映射内容的引用,这意味着v
的存在需要借用映射,直到v
停止使用。因此,这与删除和插入调用重叠,并禁止它们。
现在有各种各样的方法来解决这个问题。由于在这种特定情况下,您使用的是u64
,即Copy
,因此您只需取消引用,它就会复制您从映射中获得的值,从而无需借用:
if r.contains_key(&i) {
let v = *r.get(&i).unwrap();
r.remove(&i);
r.insert(i, v+1);
}
不过,它的灵活性有限,因为它只适用于Copy
类型[0]。
在这种特定情况下,这可能没什么大不了的,因为Copy
很便宜,但出于安全性和清晰性考虑,使用Rust提供的高级API还是更有意义的,因为您最终需要它们来处理不那么琐碎的类型。
最简单的方法是只使用get_mut
:其中get
返回一个选项
if let Some(v) = r.get_mut(&i) {
*v += 1;
}
对于您的用例来说已经足够了。
第二个选择是入口应用编程接口,这将永远毁掉你的所有其他hashmap应用编程接口。我不是在开玩笑,其他所有语言都变得可笑地令人沮丧,你可能想避免点击那个链接(尽管你最终还是需要了解它,因为它解决了真正的借用和效率问题)。
它在这里并没有真正展示它的内容,因为你的用例很简单,而且比工作做得更多,但是无论如何,你可以把增量写为:
r.entry(i).and_modify(|v| *v+=1);
顺便说一句,在大多数语言中(当然在Rust中也是如此),当您在hashmap中插入一个项目时,如果有旧值,旧值就会被删除。所以
删除
调用已经是多余的,完全没有必要。
模式匹配一个
选项
(例如HashMap::get
返回的选项)通常比痛苦地按程序执行所有低级位更安全、更干净、更快。
因此,即使不使用高级API,原始代码也可以简化为:
if let Some(&v) = r.get(&i) {
r.insert(i, v+1);
}
我仍然推荐
get_mut
版本,因为它更简单,避免了双重查找,并且适用于非Copy
类型,但YMMV。
与大多数语言不同的是,Rust的
HashMap::插入
返回旧值(f any),这不是一个问题,但在某些情况下可能很有用。
[0]以及通过显式调用
,这可能会或可能不会转化为显著的性能影响,具体取决于要克隆的类型。来克隆
对象。clone()
我在Spring Data JPA/EclipseLink环境中有一个实体(其主键不是由序列生成的),如下所示: 并且我正在尝试从表中删除一行并重新插入它(使用相同的主键)。 我的方法是调用deleteAll()来清理表,然后保存()新的实体: 但这给了我一个错误: 我做错了什么?我不明白为何要将该实体合并,而不是简单地将其删除后重新插入。 谢谢你的帮助!
为了快速地将数据插入到数据库中,我一直在尝试生成一个巨大的SQL(大约200个查询),但由于某种原因,我得到了SQL错误,但不确定是什么导致了它。 错误: SQL错误(1064):您的SQL语法有错误;查看与您的MySQL server版本相对应的手册,以了解在第8行附近使用的正确语法 下面是我的一部分代码: 你可以在Pastebin上找到我的完整SQL。 不知道是什么原因造成的,因为后面的“6”
我正在尝试在表a中插入外键(在phpmyadmin中): 将表A添加外键(id_B)引用B(id_B); 但我得到了一个错误: 表A的id_A为主键,表B的id_B为主键。这两个表都使用innoDB作为存储引擎,表A中的id_B列和表B中的id_B列具有相同的类型。 出了什么问题,我该如何解决?
但这给了我这个错误: 我做错了什么?我不明白为什么它试图合并实体,而不是简单地在删除后重新插入它。 谢谢你的帮助!
新数组列表 我用多头填充这个数组列表。 当我试图将其插入postgresql时,我使用以下方法: 使用JDBC模板。但是当我试图运行这段代码时,它在“ARRAY[?]”上给出了一个错误。但如果temp2是一个单一的数字,比如:1253214,它就可以工作。有人有主意吗? 我的错误是: PreparedStatementCallback;错误的SQL语法[UPDATE pb1plnitm SET p
尝试使用此查询 #1064-您的SQL语法有错误; 表和几乎完全相同-有相同的列。 请求中有什么错误?