我一直在更新库以使用Rust的新关联类型。该库为构建DSP图提供了Node
特性。下面是该特征的简化版本,它产生了我在我的库中遇到的相同错误。
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() {}
这是错误消息
<anon>:15:19: 15:49 error: the type of this value must be known in this context
<anon>:15 input.output_requested(&mut working);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Playpen link - http://is.gd/xm0wvS
考虑到self.inputs()
返回N
N: Node<Output = <Self as Node>::Output>
,我认为rustc应该有足够的input
类型信息来满足对{{1}的调用方法?
任何帮助都非常感谢!
答案 0 :(得分:4)
首先:给定实现x
的对象Node
,x.inputs()
获取通用参数N
并返回Vec<&mut N>
。
现在让我们写出output_requested
中发生的更明确类型的版本。
(顺便说一下,IntoIterator
循环基于新的for
基础,不再需要.into_iter()
。)
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;
}
}
那么,那么;我们可以对这种类型N
有什么看法?我们能解决吗?
它来自self.inputs()
,引入了它实施的约束Node<Output = <Self as Node>::Output>
;
在对象上,您调用方法self.output_requested(&mut <Self as Node>::Output)
,该方法仅确认前一点。
因此,我们所知道的N
就是它实现Node
与我们的类型Output
相同。但这可能是两种完全不同的类型,如:
impl Node for A {
type Output = Out;
…
}
impl Node for B {
type Output = Out;
…
}
因此,您可以看到无法确定N
是什么;它总是Self
,但也可能有其他可能性,因此无法静态解决并被禁止。