Generics 将关联类型作为参数编写递归特征方法时出错

Generics 将关联类型作为参数编写递归特征方法时出错,generics,recursion,rust,traits,associated-types,Generics,Recursion,Rust,Traits,Associated Types,我一直在更新一个库以使用Rust的新关联类型。该库提供了一个节点特性,用于构建DSP图形。下面是trait的简化版本,它会产生与我在库中遇到的错误相同的错误 use std::default::Default; use std::num::Float; trait Node { type Output: Default + Float; fn inputs<N>(&mut self) -> Vec<&mut N>

我一直在更新一个库以使用Rust的新关联类型。该库提供了一个
节点
特性,用于构建DSP图形。下面是trait的简化版本,它会产生与我在库中遇到的错误相同的错误

use std::default::Default;
use std::num::Float;

trait Node {
    type Output: Default + Float;

    fn inputs<N>(&mut self) -> Vec<&mut N>
        where
            N: Node<Output = <Self as Node>::Output>;

    fn output_requested(&mut self, output: &mut <Self as Node>::Output) {
        for input in self.inputs().into_iter() {
            let mut working: <Self as Node>::Output = Default::default();
            input.output_requested(&mut working);
            //    ^~~~~ ERROR
            *output = *output + working;
        }
    }

}

fn main() {}
使用std::default::default;
使用std::num::Float;
特征节点{
类型输出:默认+浮点;
fn输入(&mut self)->Vec
哪里
N:节点;
请求的fn输出(&mut self,输出:&mut::output){
用于在self.inputs()中输入到_iter()中{
让mut工作:::输出=默认::默认();
输入。请求的输出(多个工作(&M);
//^~~~~错误
*输出=*输出+工作;
}
}
}
fn main(){}
这是错误消息

<anon>:15:19: 15:49 error: the type of this value must be known in this context
<anon>:15             input.output_requested(&mut working);
                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

考虑到
self.inputs()
返回
N
where
N:Node
,我认为RUSC应该有足够的
input
类型信息来满足对
输出所请求的方法的调用


非常感谢您的帮助

首先:给定一个对象
x
实现
节点
x.inputs()
接受一个通用参数
N
并返回
Vec

现在,让我们写出一个更明确的类型版本,描述所请求的
输出中发生的情况

(顺便说一句,在
for
循环的
基础上,有了新奇的
into迭代器,
into_iter()
不再是必需的。)


因此,您可以看到不可能确定
N
是什么;它可以总是
Self
,但也可能有其他的可能性,因此不能静态地解析它,因此它是被禁止的。

首先:给定一个对象
x
实现
节点
x.inputs()
接受一个通用参数
N
,并返回
Vec

现在,让我们写出一个更明确的类型版本,描述所请求的
输出中发生的情况

(顺便说一句,在
for
循环的
基础上,有了新奇的
into迭代器,
into_iter()
不再是必需的。)


因此,您可以看到不可能确定
N
是什么;它总是可以是
Self
,但也可能有其他的可能性,因此它不能静态地解决,是被禁止的。

我认为问题在于编译器无法在调用
输入时确定
N
的类型。您已经告诉它必须实现
节点
,但我看不到任何方法可以让它计算出实际的具体类型。我尝试将一个
N
参数添加到
output\u request
,但它无法统一这两个不同的
输出。老实说,没有更具体的想法,我不知道如何修复它。进一步澄清:我找不到解决方法的问题是让编译器相信添加的结果与
*a
的类型相同。如果将
类型输出
更改为其他内容,例如
类型NodeOut
,则更容易看到这一点。然后,您在错误中看到的
Output
正在谈论
Add::Output
。它是否与对象安全有关@DK。啊。首先,为了澄清,所有输入应具有与
Self
相同的
Output
类型。我的印象是
N:Node
相当于说
N
Output
类型必须与
Self
Output
类型相同(考虑到该类型受
Float
的约束,添加和分配应该是合适的)?也许我真正想要的是
where::Buffer=::Buffer
,它还没有实现?顺便说一句,
output\u请求的
可以被重写,以不同的方式变异
输出
arg,但是默认情况下它只对所有输入求和。@ker我认为不是这种情况,因为
self.inputs()
返回一个泛型向量
N:Node
(不是trait对象).我认为问题在于编译器无法在调用
输入时确定
N
的类型。您已经告诉它必须实现
节点
,但我看不到任何方法可以让它计算出实际的具体类型。我尝试将一个
N
参数添加到
output\u request
,但它无法统一这两个不同的
输出。老实说,没有更具体的想法,我不知道如何修复它。进一步澄清:我找不到解决方法的问题是让编译器相信添加的结果与
*a
的类型相同。如果将
类型输出
更改为其他内容,例如
类型NodeOut
,则更容易看到这一点。然后,您在错误中看到的
Output
正在谈论
Add::Output
。它是否与对象安全有关@DK。啊。首先,为了澄清,所有输入应具有与
Self
相同的
Output
类型。我的印象是
N:Node
相当于说
N
Output
类型必须与
Self
Output
类型相同(考虑到该类型受
Float
的约束,添加和分配应该是合适的)?也许我真正想要的是
where::Buffer=::Buffer
,它还没有实现?顺便说一句,
output\u请求的
可以被重写,以不同的方式变异
输出
arg,但是默认情况下它只对所有输入求和。@ker我认为不是这种情况,因为
self.inputs()
返回一个泛型向量
N:Node
(不是trait对象)。
fn output_requested(&mut self, output: &mut <Self as Node>::Output) {
    let inputs: Vec<&mut N> = self.inputs();
    for input in inputs {  // input: &mut N
        let mut working: <Self as Node>::Output = Default::default();
        input.output_requested(&mut working);
        *output = *output + working;
    }
}
impl Node for A {
    type Output = Out;
    …
}

impl Node for B {
    type Output = Out;
    …
}