通用高阶函数引用错误
Generic higher-order function reference error
我整晚都在为这个问题苦苦思索。我正在尝试实施 to_hash_map
方法,以便我可以:
struct Person {
id: i32,
first_name: &'static str,
}
fn main() {
let brad = Person {
id: 1,
first_name: "brad",
};
let barb = Person {
id: 2,
first_name: "Barb",
};
let a = vec![brad, barb];
let key_func = |i: &Person| -> i32 { i.id };
let value_func = |i: &Person| -> &str { i.first_name };
let map = a.iter().to_hash_map(key_func, value_func);
println!("{:?}", map)
}
并希望得到 HashMap
{
1: "brad",
2: "barb"
}
这是我的最佳表现:
trait ToHashMap<T,K,V, FK, FV>
where K:Hash,
K:Eq,
FK:Fn(&T)->K,
FV:Fn(&T)->V {
fn to_hash_map(&self, key_func: FK, value_func: FV) -> HashMap<K, V>;
}
impl<T, K, V, FK, FV, I> ToHashMap<T, K, V, FK, FV> for I
where K: Hash,
K: Eq,
FK: Fn(&T) -> K,
FV: Fn(&T) -> V,
I: Iterator<Item = T>
{
fn to_hash_map(&self, key_func: FK, value_func: FV) -> HashMap<K, V>{
let mut hm: HashMap<K, V> = HashMap::new();
loop {
match self.next() {
Some(x) => {
hm.insert(key_func(&x), value_func(&x));
}
None => break,
}
}
hm
}
}
但我收到错误消息:
error: type mismatch: the type `[closure@src/main.rs:92:20: 92:48]` implements the trait `for<'r> core::ops::Fn<(&'r Person,)>`, but the trait `for<'r> core::ops::Fn<(&'r &Person,
)>` is required (expected &-ptr, found struct `Person`) [E0281]
src/main.rs:94 let map = a.iter().to_hash_map(key_func, value_func);
我觉得我很亲近。感谢您的帮助:)
问题是 a.iter()
returns 一个迭代器,它的项是 &Person
。 ToHashMap
实现的特征边界要求键和值函数采用 &T
,其中 T = Item
,因此 T = &Person
,因此函数参数为 & &Person
, 这与您的功能不符。
你必须以某种方式放宽边界,但恐怕我的 Rust 知识不足以准确说明如何放宽。
你们确实很亲近
您面临的第一个问题是 iter()
生成 &Person
类型的 Iterator::Item
,因此您传递给闭包的 &x
是 [=16 类型=].
您可以更改闭包的类型以采用 &&Person
或使用 into_iter
.
消耗向量 a
我遇到的另一个小问题是你不能通过不可变引用来获取迭代器:你需要修改迭代器来迭代。按值获取迭代器更简单。
总而言之,通过这两个调整我们可以得到(消耗向量):
trait ToHashMap<T, K, V, FK, FV>
where K: Hash,
K: Eq,
FK: Fn(&T)->K,
FV: Fn(&T)->V {
fn to_hash_map(self, key_func: FK, value_func: FV) -> HashMap<K, V>;
}
impl<T, K, V, FK, FV, I> ToHashMap<T, K, V, FK, FV> for I
where K: Hash,
K: Eq,
FK: Fn(&T) -> K,
FV: Fn(&T) -> V,
I: Iterator<Item = T>
{
fn to_hash_map(self, key_func: FK, value_func: FV) -> HashMap<K, V> {
let mut hm: HashMap<K, V> = HashMap::new();
for x in self {
hm.insert(key_func(&x), value_func(&x));
}
hm
}
}
然后 it compiles and runs 并产生:
{2: "Barb", 1: "brad"}
符合预期。
我整晚都在为这个问题苦苦思索。我正在尝试实施 to_hash_map
方法,以便我可以:
struct Person {
id: i32,
first_name: &'static str,
}
fn main() {
let brad = Person {
id: 1,
first_name: "brad",
};
let barb = Person {
id: 2,
first_name: "Barb",
};
let a = vec![brad, barb];
let key_func = |i: &Person| -> i32 { i.id };
let value_func = |i: &Person| -> &str { i.first_name };
let map = a.iter().to_hash_map(key_func, value_func);
println!("{:?}", map)
}
并希望得到 HashMap
{
1: "brad",
2: "barb"
}
这是我的最佳表现:
trait ToHashMap<T,K,V, FK, FV>
where K:Hash,
K:Eq,
FK:Fn(&T)->K,
FV:Fn(&T)->V {
fn to_hash_map(&self, key_func: FK, value_func: FV) -> HashMap<K, V>;
}
impl<T, K, V, FK, FV, I> ToHashMap<T, K, V, FK, FV> for I
where K: Hash,
K: Eq,
FK: Fn(&T) -> K,
FV: Fn(&T) -> V,
I: Iterator<Item = T>
{
fn to_hash_map(&self, key_func: FK, value_func: FV) -> HashMap<K, V>{
let mut hm: HashMap<K, V> = HashMap::new();
loop {
match self.next() {
Some(x) => {
hm.insert(key_func(&x), value_func(&x));
}
None => break,
}
}
hm
}
}
但我收到错误消息:
error: type mismatch: the type `[closure@src/main.rs:92:20: 92:48]` implements the trait `for<'r> core::ops::Fn<(&'r Person,)>`, but the trait `for<'r> core::ops::Fn<(&'r &Person,
)>` is required (expected &-ptr, found struct `Person`) [E0281]
src/main.rs:94 let map = a.iter().to_hash_map(key_func, value_func);
我觉得我很亲近。感谢您的帮助:)
问题是 a.iter()
returns 一个迭代器,它的项是 &Person
。 ToHashMap
实现的特征边界要求键和值函数采用 &T
,其中 T = Item
,因此 T = &Person
,因此函数参数为 & &Person
, 这与您的功能不符。
你必须以某种方式放宽边界,但恐怕我的 Rust 知识不足以准确说明如何放宽。
你们确实很亲近
您面临的第一个问题是 iter()
生成 &Person
类型的 Iterator::Item
,因此您传递给闭包的 &x
是 [=16 类型=].
您可以更改闭包的类型以采用 &&Person
或使用 into_iter
.
a
我遇到的另一个小问题是你不能通过不可变引用来获取迭代器:你需要修改迭代器来迭代。按值获取迭代器更简单。
总而言之,通过这两个调整我们可以得到(消耗向量):
trait ToHashMap<T, K, V, FK, FV>
where K: Hash,
K: Eq,
FK: Fn(&T)->K,
FV: Fn(&T)->V {
fn to_hash_map(self, key_func: FK, value_func: FV) -> HashMap<K, V>;
}
impl<T, K, V, FK, FV, I> ToHashMap<T, K, V, FK, FV> for I
where K: Hash,
K: Eq,
FK: Fn(&T) -> K,
FV: Fn(&T) -> V,
I: Iterator<Item = T>
{
fn to_hash_map(self, key_func: FK, value_func: FV) -> HashMap<K, V> {
let mut hm: HashMap<K, V> = HashMap::new();
for x in self {
hm.insert(key_func(&x), value_func(&x));
}
hm
}
}
然后 it compiles and runs 并产生:
{2: "Barb", 1: "brad"}
符合预期。