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