Для упражнения в книге Rust, включающего замыкания и обобщения, я пытаюсь реализовать метод для структуры Cacher
, который может принимать значение практически любого типа; выполнить операцию над ним и сохранить результат в HashMap
, где значение является ключом, а результат - значением, чтобы в случае дорогостоящих операций в следующий раз, когда значение пришло, результат уже был под рукой в HashMap
.
После долгой жизни и владения мне пришла в голову идея немного дифференцировать код в зависимости от того, является ли значение скалярным / реализующим признак Copy
или сложной кучей. сохраненный Clone
тип.
Это решило проблемы владения, но теперь компилятор выдает ошибку, потому что две версии метода имеют одно и то же имя.
Запрещено ли перегружать методы в Rust? Как я могу решить эту проблему иначе (поскольку наименование метода по-разному, в зависимости от типа значения, отрицает саму цель реализации обобщений)?
#![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));
}
error[E0592]: duplicate definitions with name `value`
--> src/main.rs:32:5
|
32 | / fn value(&'a mut self, newVal: V) -> &'a V {
33 | | let k = newVal;
34 | | match self.value.get(newVal) {
35 | | Some(res) => res,
... |
40 | | }
41 | | }
| |_____^ duplicate definitions for `value`
...
49 | / fn value(&'a mut self, newVal: W) -> &'a W {
50 | | let k = newVal.clone();
51 | | match self.value.get(&newVal) {
52 | | Some(res) => res,
... |
58 | | }
59 | | }
| |_____- other definition for `value`