Возможно ли реализовать один и тот же метод по-разному для разных черт, используя дженерики? - PullRequest
0 голосов
/ 18 марта 2020

Для упражнения в книге 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`
...