generics - 为什么 impl 不在范围内
问题描述
我是 Rust 新手,在我的学习玩具项目中,我需要一个带有可变节点的图形数据结构,所以我想出了:
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);
}
这个想法是,我希望节点可以从另一种数据类型构造,但该数据不包含在图表中,因此是关联类型而不是通用参数。节点 T 稍后将包含连接,这些连接只是指向其他节点的弱指针,但对于这个问题并不真正相关。编译时出现错误:
error[E0599]: no function or associated item named `new` found for type `C` in the current scope
--> src/main.rs:26:61
|
26 | graph.insert(key.clone(), Rc::new(RefCell::new( C::new( *connections.get(key).unwrap() ))));
| ^^^^^^ function or associated item not found in `C`
|
= help: items from traits can only be used if the trait is implemented and in scope
= note: the following trait defines an item `new`, perhaps you need to implement it:
candidate #1: `Constructible`
我不明白为什么可构造的实现不在范围内,或者还有什么不正确的。如果这是一种实现这一点的单一方式,我将很高兴收到建议!
解决方案
在 的声明中new<C>()
,类型参数C
是一个没有约束的新类型变量。您似乎打算T
将其作为的实例的关联类型Constructible
,您可以这样表达:
pub fn new(connections: HashMap<K, T::C>) -> HashedGraph<K, T> {
...
}
但是,您的代码还有许多其他问题:
- 您正在实例化对象,
&str
但您只添加Constructible
了String
. 这些是不同的类型。 - 您不需要使用
hashmap.get(key)
来访问该值。您可以只使用iter()
- 或在这种情况下drain()
,因为无论如何您都将所有值从一个容器移动到另一个容器,因此如果您不需要原始容器,这将避免借用问题HashMap
。 Constructible
的类型参数是多余的。这将永远是Self
。T
可以推断的唯一方法fn new() -> T
是调用者选择使用它的位置。理论上,另一个实现Constructible
可能具有相同的关联C
类型,所以这还不够。这意味着在构建HashedGraph
.
这是您编译的代码版本,尽管我对您真正想要实现的目标做了一些假设。
推荐阅读
- objective-c - 验证目录是否为捆绑包
- java - 迭代多个 CSV 并加入 Spark SQL
- delphi - AutoCAD 类型库在 Windows 10 中不起作用
- firebase - ios上没有recaptcha的离子firebase phoneAuth
- javascript - 限制用户在 PHP 中查看页面
- r - 将 RStudio 控制台中的文本复制为“纯文本”
- java - 尝试在运行时使用反射更改属性的值会导致 NullPointerException
- javascript - Tensorflow.js - 安全性:导入的模型是否安全?
- laravel - 如何将数据从 User.php 传递到页面
- sql-server - ER图:未连接到任何其他表的表