Generics 一般高阶函数引用错误

Generics 一般高阶函数引用错误,generics,rust,higher-order-functions,Generics,Rust,Higher Order Functions,我整晚都在用头撞这个。我正在尝试实现一个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_n

我整晚都在用头撞这个。我正在尝试实现一个
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
    }
}
trait-ToHashMap
其中K:Hash,
K:Eq,
FK:Fn&T)->K,
FV:Fn&T)->V{
fn to_hash_map(&self,key_func:FK,value_func:FV)->HashMap;
}
I的impl-ToHashMap
其中K:Hash,
K:Eq,
FK:Fn&T)->K,
FV:Fn&T)->V,
I:迭代器
{
fn到\u散列\u映射(&self,key\u func:FK,value\u func:FV)->HashMap{
让mut-hm:HashMap=HashMap::new();
环路{
匹配self.next(){
一些(x)=>{
hm.insert(键函数(&x)、值函数(&x));
}
无=>中断,
}
}
陛下
}
}
但我得到了一个错误:

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);
错误:类型不匹配:类型不匹配`[closure@src/main.rs:92:20:92:48]`实现trait`for`,但trait`for`是必需的(预期为&-ptr,找到结构`Person`)[E0281]
src/main.rs:94 let map=a.iter().to_hash_map(key_func,value_func);

我觉得我离得太近了。感谢您的帮助:)

问题在于
a.iter()
返回一个迭代器,其项为
&Person
ToHashMap
impl的特征边界要求键函数和值函数采用
&T
,其中
T=Item
,因此
T=&Person
,因此函数参数为
&Person
,与函数不匹配


您必须以某种方式放宽界限,尽管我担心我的知识不足以确切说明如何进行。

问题是
a.iter()
返回一个迭代器,其项为
&Person
ToHashMap
impl的特征边界要求键函数和值函数采用
&T
,其中
T=Item
,因此
T=&Person
,因此函数参数为
&Person
,与函数不匹配


你必须以某种方式放宽限制,尽管我恐怕对锈蚀的了解还不足以确切地说明如何进行。

你确实非常接近

您面临的第一个问题是
iter()
生成
迭代器::Item
类型为
&Person
,因此传递给闭包的
&x
类型为
&Person

您可以改变闭包的类型以获取一个
&&Person
,或者使用
将向量
a
消耗到iter

我遇到的另一个小问题是,不能通过不可变引用获取迭代器:需要修改迭代器进行迭代。按值获取迭代器更简单

总之,通过这两个调整,我们可以得到(使用向量):


正如所料。

你确实非常接近

您面临的第一个问题是
iter()
生成
迭代器::Item
类型为
&Person
,因此传递给闭包的
&x
类型为
&Person

您可以改变闭包的类型以获取一个
&&Person
,或者使用
将向量
a
消耗到iter

我遇到的另一个小问题是,不能通过不可变引用获取迭代器:需要修改迭代器进行迭代。按值获取迭代器更简单

总之,通过这两个调整,我们可以得到(使用向量):


正如所料。

如果您可以使用发布MVCE,那就太好了。很接近,只是缺少了一个自包含的示例。我将把大多数类型参数从trait移到trait方法
T
需要保留在trait上,否则您无法在
impl
中正确绑定
I
,但其他类型参数与实现trait的类型无关,仅在调用
到\u hash\u map
期间才有意义。如果您可以使用发布MVCE,那就太好了。很接近,只是缺少了一个自包含的示例。我将把大多数类型参数从trait移到trait方法
T
需要保留在trait上,否则您无法在
impl
中正确绑定
I
,但其他类型参数与实现trait的类型无关,仅在调用
到\u hash\u map
期间才有意义。回答得好!我从中学到了很多(我才刚刚开始我的生锈之旅)。@SimonWhitehead:欢迎乘坐火车,小心,有人说这是一种上瘾的语言;)谢谢当你看到答案时,它似乎是如此明显:)答案很好!我从中学到了很多(我才刚刚开始我的生锈之旅)。@SimonWhitehead:欢迎乘坐火车,小心,有人说这是一种上瘾的语言;)谢谢当你看到答案时,这似乎是显而易见的:)
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
    }
}
{2: "Barb", 1: "brad"}