Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/email/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Generics 是否可以使用泛型以不同的方式针对不同的特性实现相同的方法?_Generics_Rust_Traits - Fatal编程技术网

Generics 是否可以使用泛型以不同的方式针对不同的特性实现相同的方法?

Generics 是否可以使用泛型以不同的方式针对不同的特性实现相同的方法?,generics,rust,traits,Generics,Rust,Traits,对于Rust book中涉及闭包和泛型的一个练习,我试图在结构缓存器上实现一个方法,该方法可以接受几乎任何类型的值;对其执行操作并将结果存储在HashMap中,其中值是键,结果是值,因此,如果是昂贵的操作,下一次出现值时,结果已经在HashMap中 在经历了大量的生命周期和所有权的挣扎之后,我想出了一个主意,就是根据值是标量/实现Copytrait还是复杂的堆存储Clone类型来区分代码 它解决了所有权问题,但现在编译器给出了一个错误,因为该方法的两个版本具有相同的名称 是否禁止在铁锈中超载?否

对于Rust book中涉及闭包和泛型的一个练习,我试图在结构
缓存器
上实现一个方法,该方法可以接受几乎任何类型的值;对其执行操作并将结果存储在
HashMap
中,其中值是键,结果是值,因此,如果是昂贵的操作,下一次出现值时,结果已经在
HashMap

在经历了大量的生命周期和所有权的挣扎之后,我想出了一个主意,就是根据值是标量/实现
Copy
trait还是复杂的堆存储
Clone
类型来区分代码

它解决了所有权问题,但现在编译器给出了一个错误,因为该方法的两个版本具有相同的名称

是否禁止在铁锈中超载?否则我如何解决这个问题(因为根据值的类型对方法进行不同的命名会破坏实现泛型的目的)


是否禁止在生锈情况下超载已经回答:其他人询问此练习:;根据值[…]是实现
Copy
trait还是实现复杂的堆存储
Clone
type,这不是一个有用的区别。任何实现
Copy
的操作都会实现
Clone
@Shepmaster谢谢!之前给出的这个练习的答案非常有启发性,但是如果我能借用你更多的注意力的话,仍然有一些问题困扰着我。我知道在菊花链连接self.values.get()和self.values.insert()时,会出现值的borroing,因为get具有&self隐式参数,而insert具有&mut self。但我不确定我是否完全理解在整个范围内暂停借款的意义。意思是:我希望get()的结果被保留,而值的中间借用被释放
#![allow(unused_variables)]

use std::collections::HashMap;

struct Cacher<'a, T, V>
where
    T: Fn(V) -> V,
    V: std::cmp::Eq + std::hash::Hash,
{
    calculation: T,
    value: HashMap<V, V>,
}

impl<'a, T, V> Cacher<'a, T, V>
where
    T: Fn(V) -> V,
    V: std::cmp::Eq + std::hash::Hash,
{
    fn new(calculation: T) -> Cacher<'a, T, V> {
        Cacher {
            calculation,
            value: HashMap::new(),
        }
    }
}

impl<'a, T, V> Cacher<'a, T, V>
where
    T: Fn(V) -> V,
    V: std::cmp::Eq + std::hash::Hash + Copy,
{
    fn value(&'a mut self, newVal: V) -> &'a V {
        let k = newVal;
        match self.value.get(newVal) {
            Some(res) => res,
            None => {
                self.value.insert(newVal, (self.calculation)(&newVal));
                self.value.get(k).unwrap()
            }
        }
    }
}

impl<'a, T, W> Cacher<'a, T, W>
where
    T: Fn(W) -> W,
    W: std::cmp::Eq + std::hash::Hash,
{
    fn value(&'a mut self, newVal: W) -> &'a W {
        let k = newVal.clone();
        match self.value.get(&newVal) {
            Some(res) => res,
            None => {
                let res = (self.calculation)(newVal);
                self.value.insert(&k, res);
                self.value.get(k)
            }
        }
    }
}

fn main() {
    let op = |val| val;

    let mut c = Cacher::new(op);
    let v = 5;

    println!("{} -> {}", v, c.value(&v));
}