Generics 带泛型的Deref强制

Generics 带泛型的Deref强制,generics,rust,dereference,Generics,Rust,Dereference,我正在尝试编写一个参数化函数if\u found\u update,该函数在哈希值存在时更新该值: use std::collections::HashMap; fn if_found_update<K, V>(data: &mut HashMap<K, V>, k: &K, v: &V, f: &Fn(&V, &V) -> V) -> bool where K: std::cmp::Eq,

我正在尝试编写一个参数化函数
if\u found\u update
,该函数在哈希值存在时更新该值:

use std::collections::HashMap;

fn if_found_update<K, V>(data: &mut HashMap<K, V>, k: &K, v: &V, f: &Fn(&V, &V) -> V) -> bool
    where K: std::cmp::Eq,
          K: std::hash::Hash
{
    if let Some(e) = data.get_mut(k) {
        *e = f(e, v);
        return true;
    }
    false
}

fn main() {
    let mut h: HashMap<String, i64> = HashMap::new();
    h.insert("A".to_string(), 0);
    let one = 1 as i64;
    fn update(e1: &i64, e2: &i64) -> i64 {
        e1 + e2
    };
    let k: &str = &"A".to_string();
    println!("{}",
             if_found_update(&mut h, &"A".to_string(), &one, &update)); // works
    println!("{}", if_found_update(&mut h, k, &one, &update)); // fails to compile
}
我认为这是因为它没有为适当的解除胁迫而努力。有没有办法让这样的东西发挥作用

的某些方法,例如和,可以接收密钥类型的借用版本。他们是通过利用这种特质来做到这一点的。它们是类型参数
Q
的泛型,该类型参数可以是表示密钥借用的任何类型。它是这样工作的:当
X
实现
借用
时,意味着
&X
可以作为
&Y
借用。例如,
&String
可以作为
&str
借用

您可以通过在函数中引入一个额外的类型参数并添加正确的边界来利用这一点

use std::borrow::Borrow;
use std::collections::HashMap;
use std::hash::Hash;

fn if_found_update<K, V, Q>(data: &mut HashMap<K, V>, k: &Q, v: &V, f: &Fn(&V, &V) -> V) -> bool
    where K: Hash + Eq + Borrow<Q>,
          Q: ?Sized + Hash + Eq
{
    if let Some(e) = data.get_mut(k) {
        *e = f(e, v);
        return true;
    }
    false
} 

fn main() {
    let mut h: HashMap<String, i64> = HashMap::new();
    h.insert("A".to_string(), 0);
    let one = 1 as i64;
    fn update(e1: &i64, e2: &i64) -> i64 { e1 + e2 }
    let k: &str = "A";
    println!("{}", if_found_update(&mut h, &"A".to_string(), &one, &update));
    println!("{}", if_found_update(&mut h, k, &one, &update));
}
使用标准::借用::借用;
使用std::collections::HashMap;
使用std::hash::hash;
fn如果发现更新(数据:&mut HashMap,k:&Q,v:&v,f:&fn(&v,&v)->v)->bool
其中K:Hash+Eq+Borrow,
Q:?大小+散列+相等
{
如果让一些(e)=数据。获取(k){
*e=f(e,v);
返回true;
}
假的
} 
fn main(){
让mut h:HashMap=HashMap::new();
h、 插入(“A.”到字符串(),0);
设一=1为i64;
fn更新(e1:&i64,e2:&i64)->i64{e1+e2}
设k:&str=“A”;
println!(“{}”,如果您找到了更新(&mut h,&A.),则返回字符串(),一,&update));
println!(“{}”,如果你找到了更新(&muth,k,&one,&update));
}

谢谢!我试着借用,但用得不对。