Generics 为什么impl不在范围内

Generics 为什么impl不在范围内,generics,rust,associated-types,Generics,Rust,Associated Types,我是一个新手,在我的学习玩具项目中,我需要一个具有可变节点的图形数据结构,因此我提出: use std::cell::RefCell; use std::clone::Clone; use std::cmp::Eq; use std::collections::HashMap; use std::hash::Hash; use std::rc::Rc; pub trait Constructible<T> { type C; fn new(Self::C) ->

我是一个新手,在我的学习玩具项目中,我需要一个具有可变节点的图形数据结构,因此我提出:

use std::cell::RefCell;
use std::clone::Clone;
use std::cmp::Eq;
use std::collections::HashMap;
use std::hash::Hash;
use std::rc::Rc;

pub trait Constructible<T> {
    type C;
    fn new(Self::C) -> T;
}

#[derive(Debug)]
pub struct HashedGraph<K: Eq + Hash + Clone, T: Constructible<T>> {
    graph: HashMap<K, Rc<RefCell<T>>>,
}

impl<K, T> HashedGraph<K, T>
where
    K: Eq + Hash + Clone,
    T: Constructible<T>,
{
    pub fn new<C>(connections: HashMap<K, C>) -> HashedGraph<K, T> {
        let mut graph: HashMap<K, Rc<RefCell<T>>> = HashMap::new();

        for key in connections.keys() {
            graph.insert(
                key.clone(),
                Rc::new(RefCell::new(C::new(*connections.get(key).unwrap()))),
            );
        }

        HashedGraph { graph }
    }
}

impl Constructible<String> for String {
    type C = String;
    fn new(instring: String) -> String {
        instring
    }
}

fn main() {
    let mut test = HashMap::new();
    test.insert("one", "ONE");
    test.insert("two", "TWO");
    let hg = HashedGraph::new(test);
}

我不明白为什么constructible的实现不在范围内,或者其他什么是不正确的。如果这是一种非传统的实施方式,我将非常高兴收到建议

new()
的声明中,类型参数
C
是一个没有约束的新类型变量。似乎您希望它是
T
Constructible
实例中的关联类型,您可以这样表示:

pub fn new(connections: HashMap<K, T::C>) -> HashedGraph<K, T> {
 ...
}
pub fn new(连接:HashMap)->HashedGraph{
...
}
但是,您的代码还有许多其他问题:

  • 您正在使用
    &str
    实例化对象,但您只为
    字符串添加了一个
    可构造的
    实例。这些是不同的类型
  • 您不需要使用
    hashmap.get(key)
    来访问该值。您可以只使用
    iter()
    ——或者在本例中使用
    drain()
    ,因为您要将所有值从一个容器移动到另一个容器,因此如果您不需要原始的
    HashMap
    ,这将避免借用问题
  • 可构造的
    的类型参数是冗余的。这永远是
    Self
  • fn new()->T
    中推断
    T
    的唯一方法是从调用方选择使用它的位置。理论上,
    Constructible
    的另一个实现可能具有相同的关联
    C
    类型,因此这还不够。这意味着您在构造
    HashedGraph
    时需要类型注释

虽然我对您真正想要实现的目标做了一些假设。

关于
new
中的
C
,没有任何限制它成为
可构造的
。另外,我认为您可以直接将
转换为
/
From
,而不是引入一个新特性,因为它看起来像是一个转换。此外,为
字符串实现
可能不是您的意思,因为您在主函数中使用了
&str
。为什么
可构造的
需要关联类型?类型参数
T
在您使用它的方式中似乎是多余的,可以是
Self