使用 HashMap 实现映射迭代器的函数的生命周期问题
Lifetime problems on implementing function that maps over an iterator using a HashMap
我尝试使用 HashMap
:
实现映射迭代器的函数
use std::collections::HashMap;
use std::hash::Hash;
/// Translates every element it gets using a map. In case the map does not help, it is mapped to
/// itself.
fn translate<'a, 'b, S, T>(map: &'a HashMap<T, T>, stream: S) -> impl Iterator<Item = T> + 'a + 'b
where
S: Iterator<Item = T> + 'b,
T: Copy + Eq + Hash,
{
stream.map(|e: T| -> T { *map.get(&e).unwrap_or(&e) })
}
我收到此代码的错误消息:
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
--> src/lib.rs:11:16
|
11 | stream.map(|e: T| -> T { *map.get(&e).unwrap_or(&e) })
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 6:14...
--> src/lib.rs:6:14
|
6 | fn translate<'a, 'b, S, T>(map: &'a HashMap<T, T>, stream: S) -> impl Iterator<Item = T> + 'a + 'b
| ^^
= note: ...so that the types are compatible:
expected &&std::collections::HashMap<T, T>
found &&'a std::collections::HashMap<T, T>
note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 6:18...
--> src/lib.rs:6:18
|
6 | fn translate<'a, 'b, S, T>(map: &'a HashMap<T, T>, stream: S) -> impl Iterator<Item = T> + 'a + 'b
| ^^
note: ...so that return value is valid for the call
--> src/lib.rs:6:66
|
6 | fn translate<'a, 'b, S, T>(map: &'a HashMap<T, T>, stream: S) -> impl Iterator<Item = T> + 'a + 'b
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
我还没有弄清楚哪里出了问题,也不知道该如何解决。
我不得不猜测,因为您没有包含 MCVE。您的代码无法编译,表面上存在生命周期错误。您可能指的函数签名是:
fn translate<'a, 'b, S, T>(map: &'a HashMap<T, T>, stream: S) -> impl Iterator<Item = T> + 'a
where
S: Iterator<Item = T> + 'b,
T: Copy + Eq + Hash,
'b: 'a, // Read: "'b outlives 'a"
因为 S
的寿命可能比您的 return 值长,而且它仍然有效。
但是,我看不出这种方法有任何优势:更长的生命周期始终有效,而不是更短的生命周期,您不需要明确指出这一点。只需使用一个生命周期,如下所示。
fn translate<'a, S, T>(map: &'a HashMap<T, T>, stream: S) -> impl Iterator<Item = T> + 'a
where
S: Iterator<Item = T> + 'a,
T: Copy + Eq + Hash,
{
stream.map(move |e: T| -> T { *map.get(&e).unwrap_or(&e) })
}
如您所见,您还缺少 move
关键字,这是您的闭包绝对需要的。否则,它可能比函数拥有的地图寿命更长。
不过,这个函数还是比较密集的。如果你只在一个地方使用它,也许根本不介绍它,省去一些头痛?
我尝试使用 HashMap
:
use std::collections::HashMap;
use std::hash::Hash;
/// Translates every element it gets using a map. In case the map does not help, it is mapped to
/// itself.
fn translate<'a, 'b, S, T>(map: &'a HashMap<T, T>, stream: S) -> impl Iterator<Item = T> + 'a + 'b
where
S: Iterator<Item = T> + 'b,
T: Copy + Eq + Hash,
{
stream.map(|e: T| -> T { *map.get(&e).unwrap_or(&e) })
}
我收到此代码的错误消息:
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
--> src/lib.rs:11:16
|
11 | stream.map(|e: T| -> T { *map.get(&e).unwrap_or(&e) })
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 6:14...
--> src/lib.rs:6:14
|
6 | fn translate<'a, 'b, S, T>(map: &'a HashMap<T, T>, stream: S) -> impl Iterator<Item = T> + 'a + 'b
| ^^
= note: ...so that the types are compatible:
expected &&std::collections::HashMap<T, T>
found &&'a std::collections::HashMap<T, T>
note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 6:18...
--> src/lib.rs:6:18
|
6 | fn translate<'a, 'b, S, T>(map: &'a HashMap<T, T>, stream: S) -> impl Iterator<Item = T> + 'a + 'b
| ^^
note: ...so that return value is valid for the call
--> src/lib.rs:6:66
|
6 | fn translate<'a, 'b, S, T>(map: &'a HashMap<T, T>, stream: S) -> impl Iterator<Item = T> + 'a + 'b
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
我还没有弄清楚哪里出了问题,也不知道该如何解决。
我不得不猜测,因为您没有包含 MCVE。您的代码无法编译,表面上存在生命周期错误。您可能指的函数签名是:
fn translate<'a, 'b, S, T>(map: &'a HashMap<T, T>, stream: S) -> impl Iterator<Item = T> + 'a
where
S: Iterator<Item = T> + 'b,
T: Copy + Eq + Hash,
'b: 'a, // Read: "'b outlives 'a"
因为 S
的寿命可能比您的 return 值长,而且它仍然有效。
但是,我看不出这种方法有任何优势:更长的生命周期始终有效,而不是更短的生命周期,您不需要明确指出这一点。只需使用一个生命周期,如下所示。
fn translate<'a, S, T>(map: &'a HashMap<T, T>, stream: S) -> impl Iterator<Item = T> + 'a
where
S: Iterator<Item = T> + 'a,
T: Copy + Eq + Hash,
{
stream.map(move |e: T| -> T { *map.get(&e).unwrap_or(&e) })
}
如您所见,您还缺少 move
关键字,这是您的闭包绝对需要的。否则,它可能比函数拥有的地图寿命更长。
不过,这个函数还是比较密集的。如果你只在一个地方使用它,也许根本不介绍它,省去一些头痛?