编写具有关联类型作为参数的递归特征方法时出错

时间:2015-02-04 08:32:09

标签: generics recursion rust traits associated-types

我一直在更新库以使用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}的调用方法?

任何帮助都非常感谢!

1 个答案:

答案 0 :(得分:4)

首先:给定实现x的对象Nodex.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,但也可能有其他可能性,因此无法静态解决并被禁止。