From<&V> 特征约束的生命周期问题
Lifetime issue with From<&V> trait constraint
尽管所讨论的 V
实例已被拥有,但以下代码会产生以下生命周期错误。
use std::collections::hash_map::HashMap;
use std::cmp::Eq;
use std::hash::Hash;
trait Set<V> {
fn set(&mut self, value: V) -> Option<V>;
}
impl<'a, K: Eq + Hash + From<&'a V>, V: 'a> Set<V> for HashMap<K, V> {
fn set(&mut self, v: V) -> Option<V> {
let k = K::from(&v);
self.insert(k, v)
}
}
由此产生的错误...
|
9 | impl<'a, K: Eq + Hash + From<&'a V>, V: 'a> Set<V> for HashMap<K, V> {
| -- lifetime `'a` defined here
10 | fn set(&mut self, v: V) -> Option<V> {
11 | let k = K::from(&v);
| --------^^-
| | |
| | borrowed value does not live long enough
| argument requires that `v` is borrowed for `'a`
12 | self.insert(k, v)
13 | }
| - `v` dropped here while still borrowed
error[E0505]: cannot move out of `v` because it is borrowed
--> src/lib.rs:12:24
|
9 | impl<'a, K: Eq + Hash + From<&'a V>, V: 'a> Set<V> for HashMap<K, V> {
| -- lifetime `'a` defined here
10 | fn set(&mut self, v: V) -> Option<V> {
11 | let k = K::from(&v);
| -----------
| | |
| | borrow of `v` occurs here
| argument requires that `v` is borrowed for `'a`
12 | self.insert(k, v)
| ^ move out of `v` occurs here
使用 higher-rank trait bound 表示为 for<'a>
:
impl<K: Eq + Hash + for<'a> From<&'a V>, V> Set<V> for HashMap<K, V> {
fn set(&mut self, v: V) -> Option<V> {
self.insert(K::from(&v), v)
}
}
查看它在 playground 上的工作情况。
作为一个普通的泛型参数,生命周期 'a
由调用者决定,它比 set()
调用本身长。但是,v
的生命周期仅局限于函数体,这意味着用于调用 K::from()
的任何生命周期 'a
都可以比 V
中可能包含的内容更长寿。仅仅因为 v
是一个拥有的值并不意味着它没有与之关联的生命周期,毕竟它是通用的。编译器已经尽力了,但它的建议不是你想要的。
使用 for<'a> From<&'a V>
约束意味着 K::from()
调用将在 任何 生命周期内工作,包括 [=14= 的短函数局部生命周期].
尽管所讨论的 V
实例已被拥有,但以下代码会产生以下生命周期错误。
use std::collections::hash_map::HashMap;
use std::cmp::Eq;
use std::hash::Hash;
trait Set<V> {
fn set(&mut self, value: V) -> Option<V>;
}
impl<'a, K: Eq + Hash + From<&'a V>, V: 'a> Set<V> for HashMap<K, V> {
fn set(&mut self, v: V) -> Option<V> {
let k = K::from(&v);
self.insert(k, v)
}
}
由此产生的错误...
|
9 | impl<'a, K: Eq + Hash + From<&'a V>, V: 'a> Set<V> for HashMap<K, V> {
| -- lifetime `'a` defined here
10 | fn set(&mut self, v: V) -> Option<V> {
11 | let k = K::from(&v);
| --------^^-
| | |
| | borrowed value does not live long enough
| argument requires that `v` is borrowed for `'a`
12 | self.insert(k, v)
13 | }
| - `v` dropped here while still borrowed
error[E0505]: cannot move out of `v` because it is borrowed
--> src/lib.rs:12:24
|
9 | impl<'a, K: Eq + Hash + From<&'a V>, V: 'a> Set<V> for HashMap<K, V> {
| -- lifetime `'a` defined here
10 | fn set(&mut self, v: V) -> Option<V> {
11 | let k = K::from(&v);
| -----------
| | |
| | borrow of `v` occurs here
| argument requires that `v` is borrowed for `'a`
12 | self.insert(k, v)
| ^ move out of `v` occurs here
使用 higher-rank trait bound 表示为 for<'a>
:
impl<K: Eq + Hash + for<'a> From<&'a V>, V> Set<V> for HashMap<K, V> {
fn set(&mut self, v: V) -> Option<V> {
self.insert(K::from(&v), v)
}
}
查看它在 playground 上的工作情况。
作为一个普通的泛型参数,生命周期 'a
由调用者决定,它比 set()
调用本身长。但是,v
的生命周期仅局限于函数体,这意味着用于调用 K::from()
的任何生命周期 'a
都可以比 V
中可能包含的内容更长寿。仅仅因为 v
是一个拥有的值并不意味着它没有与之关联的生命周期,毕竟它是通用的。编译器已经尽力了,但它的建议不是你想要的。
使用 for<'a> From<&'a V>
约束意味着 K::from()
调用将在 任何 生命周期内工作,包括 [=14= 的短函数局部生命周期].