Generics 将关联类型作为参数编写递归特征方法时出错
我一直在更新一个库以使用Rust的新关联类型。该库提供了一个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>
节点
特性,用于构建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
whereN: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;
…
}