- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试编写一个函数,仅当元素大于向量中已有的最后一个元素时才将元素插入排序向量的末尾,否则返回错误并返回最大元素的引用。据我所知,这似乎没有违反任何借贷规则,但借贷检查员不喜欢它。我不明白为什么。
struct MyArray<K, V>(Vec<(K, V)>);
impl<K: Ord, V> MyArray<K, V> {
pub fn insert_largest(&mut self, k: K, v: V) -> Result<(), &K> {
{
match self.0.iter().next_back() {
None => (),
Some(&(ref lk, _)) => {
if lk > &k {
return Err(lk);
}
}
};
}
self.0.push((k, v));
Ok(())
}
}
error[E0502]: cannot borrow `self.0` as mutable because it is also borrowed as immutable
--> src/main.rs:15:9
|
6 | match self.0.iter().next_back() {
| ------ immutable borrow occurs here
...
15 | self.0.push((k, v));
| ^^^^^^ mutable borrow occurs here
16 | Ok(())
17 | }
| - immutable borrow ends here
为什么这行不通?
我们可以将任何带有 return 语句的函数转换为没有 return 语句的函数,如下所示:
fn my_func() -> &MyType {
'inner: {
// Do some stuff
return &x;
}
// And some more stuff
}
进入
fn my_func() -> &MyType {
let res;
'outer: {
'inner: {
// Do some stuff
res = &x;
break 'outer;
}
// And some more stuff
}
res
}
由此可见,借用超出了'inner
的范围。
为了借用检查的目的而不是使用以下重写有什么问题吗?
fn my_func() -> &MyType {
'outer: {
'inner: {
// Do some stuff
break 'outer;
}
// And some more stuff
}
panic!()
}
考虑到 return 语句可以防止之后发生任何可能违反借用规则的事情。
最佳答案
如果我们明确命名生命周期,insert_largest
的签名变成 fn insert_largest<'a>(&'a mut self, k: K, v: V) -> Result<(), &'a K>
.因此,当您创建返回类型时 &K
, 它的生命周期将与 &mut self
相同.
而且,事实上,您正在返回 lk
从里面self
.编译器看到对 lk
的引用逃脱匹配的范围(因为它被分配给函数的返回值,所以它必须比函数本身长寿)并且它不能在匹配结束时让借用结束。
我想你是说编译器应该更聪明并意识到 self.0.push
只有在 lk
时才能到达没有被退回。但事实并非如此。而且我什至不确定教它进行这种分析会有多困难,因为它比我今天理解借用检查器原因的方式要复杂一些。
今天,编译器看到一个引用并基本上尝试回答一个问题(“它能活多久?”)。当它看到你的返回值为lk
时, 它分配 lk
它期望从 fn 的签名返回值的生命周期('a
具有我们在上面给它的显式名称)并称之为一天。
所以,简而言之:
目前,如果可能的话,我建议只返回一个克隆而不是一个引用。我假设返回一个 Err
不是典型情况,所以性能不应该特别担心,但我不确定 K:Clone
是怎样的bound 可能适用于您正在使用的类型。
impl <K, V> MyArray<K, V> where K:Clone + Ord { // 1. now K is also Clone
pub fn insert_largest(&mut self, k: K, v: V) ->
Result<(), K> { // 2. returning K (not &K)
match self.0.iter().next_back() {
None => (),
Some(&(ref lk, _)) => {
if lk > &k {
return Err(lk.clone()); // 3. returning a clone
}
}
};
self.0.push((k, v));
Ok(())
}
}
关于return - 为什么提早归还未完成未偿还的借贷?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34845546/
我想弄清楚为什么这不起作用。 我在 Typescript 上使用 React 和 Redux。 我有以下代码: import * as React from 'react'; import * as
我想申请重新投递并使用死信 channel 。所以发现这个非常有用的apache-camel FAQ link 。我按照本网站中提到的步骤进行操作。 我添加了更多逻辑,代码可以在 github 中找到
我是一名优秀的程序员,十分优秀!