Rust 如何在函数中使用递归关联类型?

Rust 如何在函数中使用递归关联类型?,rust,Rust,我正在尝试编写一个函数,该函数可以降为任何类型的值,并将它观察到的相似性告知委托。这样做的目的是让它在所有类型的Json/Yaml/YouNameIt值中通用 下面是一个触发问题()的MVCE: pub特征值:PartialEq{ 类型项目; 类型键; fn项目选项; } 发布特性委托 { d、 某物(l); 设v=l.items().unwrap().next().unwrap(); d、 某物(1节); } 结构记录器; 记录器{}的impl #[衍生(部分)] 结构递归值; Recursi

我正在尝试编写一个函数,该函数可以降为任何类型的
,并将它观察到的相似性告知
委托。这样做的目的是让它在所有类型的Json/Yaml/YouNameIt值中通用

下面是一个触发问题()的MVCE:

pub特征值:PartialEq{
类型项目;
类型键;
fn项目选项;
}
发布特性委托
{
d、 某物(l);
设v=l.items().unwrap().next().unwrap();
d、 某物(1节);
}
结构记录器;
记录器{}的impl
#[衍生(部分)]
结构递归值;
RecursiveValue的impl值{
键入Key=usize;
类型项=递归值;
fn项目选项{
没有一个
}
}
fn main(){
设v=递归值;
设mut r=记录器;
差异(&v和&mut r);
}    
尝试编译代码时,会产生以下错误:

error[E0308]: mismatched types
  --> <anon>:19:17
   |
19 |     d.something(v.1);
   |                 ^^^ expected type parameter, found associated type
   |
   = note: expected type `&'a V`
   = note:    found type `&<V as Value>::Item`
错误[E0308]:类型不匹配
--> :19:17
|
19 | d.某物(1节);
|^^^应为类型参数,找到关联的类型
|
=注意:预期类型为`&'a V`
=注意:找到类型`&::项`

我想说关联的
类型也是
V
类型。有没有一种方法可以让这样的算法在一般情况下工作?

答案就在这本书的最后一章

在绑定中使用泛型类型时,如在
V:Value
中,可以使用
generic
语法将其一个或多个关联类型约束为特定类型

在您的情况下,它意味着将
V
约束为
Value
。由于
V
的边界是自然可用的,因此这也应该消除进一步约束
V::Item
的任何理由



我鼓励你阅读这本书来帮助你学习生锈,或者至少浏览一下,了解那里有什么可用的东西,当你遇到困难时可以参考它。

下面是一个进一步简化的例子:

pub trait Value {
    type Item;
    fn items(&self) -> &Self::Item;
}

pub trait Delegate<V> {
    fn something(&mut self, v: &V);
}

pub fn diff<V, D>(l: &V, d: &mut D)
    where V: Value,
          V::Item: Value,
          D: Delegate<V>
{
    let v = l.items();
    d.something(v);
}

fn main() {}
换句话说,这表示:

  • V
    可以是任何类型,只要它实现了
    特征
  • V::Item
    可以是任何类型,只要它实现了
    特征
  • D
    可以是任何类型,只要它实现了
    委托
    特征
该需求列表中没有列出“
V
V::Item
必须相同”。事实上,这是一个不要求它们相同的特性

在这种简化中,另一种解决方案是说
D:Delegate
。但是,这不适用于稍大的复制品:

pub fn diff<V, D>(l: &V, d: &mut D)
    where V: Value,
          V::Item: Value,
          D: Delegate<V::Item>
{
    d.something(l);
    let v = l.items();
    d.something(v);
}
pub fn diff(l:&V,d:&mut d)
式中V:值,
V::项:值,
D:代表
{
d、 某物(l);
设v=l.items();
d、 某物(v);
}
如图所示,您希望指定特征的关联类型:

pub fn diff<V, D>(l: &V, d: &mut D)
    where V: Value<Item = V>,
          D: Delegate<V>
pub fn diff(l:&V,d:&mut d)
式中V:值,
D:代表
要进一步阅读,请查看

pub fn diff<V, D>(l: &V, d: &mut D)
    where V: Value,
          V::Item: Value,
          D: Delegate<V::Item>
{
    d.something(l);
    let v = l.items();
    d.something(v);
}
pub fn diff<V, D>(l: &V, d: &mut D)
    where V: Value<Item = V>,
          D: Delegate<V>