结构的复杂特征要求

时间:2016-01-01 01:31:24

标签: struct rust traits

我有一个相当复杂的特性设置,我无法排列碎片。现在看起来大致如下:

/// Trait for models which can be gradient-optimized.
pub trait Optimizable {
    type Data;
    type Target;

    // The contract //
}

/// Trait for optimization algorithms.
pub trait OptimAlgorithm<M : Optimizable> {

    // The contract //
}

现在我希望能够允许实现OptimAlgorithm的结构体成为实现Optimizable的结构中的字段。这看起来像这样:

/// Model struct
pub struct Model<A: OptimAlgorithm<Self>> {
    alg: A,
}

impl Optimizable for Model<A> {
...
}

这不起作用,因为结构上的Self引用是无意义的。我尝试使用OptimAlgorithm的关联类型,但我需要算法在模型上是通用的,所以这不起作用。我缺少一种神奇的语法,还是需要进行大修?

编辑 -

这是一个minimal example,它显示了史蒂文答案中描述的错误E0275。它更接近我的源代码,但不那么混乱。

2 个答案:

答案 0 :(得分:4)

只需使用Model<A>代替SelfSelf仅对需要能够引用实现特征的具体类型的特征非常有用。这里,具体类型始终为Model<A>

pub trait Optimizable {
    type Data;
    type Target;

    // The contract //
}

/// Trait for optimization algorithms.
pub trait OptimAlgorithm<M: Optimizable> {

    // The contract //
}
pub struct Model<A> where A: OptimAlgorithm<Model<A>> {
    alg: A,
}

impl<A> Optimizable for Model<A>
    where A: OptimAlgorithm<Model<A>>
{
    type Data = ();
    type Target = ();
}

为了响应您的更新代码,生命周期似乎会给生锈带来麻烦。看来你可以通过使用排名更高的生命来完成这项工作,但我不知道为什么。

pub trait Optimizable {
    type Data;
    type Target;

    // The contract //
}

/// Trait for optimization algorithms.
pub trait OptimAlgorithm<M: Optimizable> {

    // The contract //
}

pub struct Algorithm;

impl Default for Algorithm {
    fn default() -> Algorithm { Algorithm }
}

impl<M: Optimizable> OptimAlgorithm<M> for Algorithm {

}


pub struct Model<'a, A> where for<'b> A: OptimAlgorithm<Model<'b, A>> {
    layer_sizes: &'a [usize],
    alg: A,
}

impl<'a, A> Model<'a, A>
    where A: for<'b> OptimAlgorithm<Model<'b, A>>
{
    pub fn new(layers: &'a [usize]) -> Model<Algorithm> {
        Model {
            layer_sizes: layers,
            alg: Algorithm::default(),
        }
    }
}

impl<'a, A> Optimizable for Model<'a, A>
    where A: for<'b> OptimAlgorithm<Model<'b, A>>
{
    type Data = ();
    type Target = ();
}

pub fn main() {
    let layers = &[1usize,2,3];
    let a = Model::<Algorithm>::new(layers as &[usize]);
}

答案 1 :(得分:2)

我认为这是一个错误。或者至少令人惊讶的行为。 如果您取消private void ButtonBase_OnClick(object sender, RoutedEventArgs e) { Typeface face = new Typeface("Candara"); FormattedText tx = new FormattedText("Hello", Thread.CurrentThread.CurrentUICulture, FlowDirection.LeftToRight, face, 70, Brushes.Black); Geometry textGeom = tx.BuildGeometry(new Point(0, 0)); Rect boundingRect = new Rect(new Point(-100000, -100000), new Point(100000, 100000)); RectangleGeometry boundingGeom = new RectangleGeometry(boundingRect); GeometryGroup group = new GeometryGroup(); group.Children.Add(boundingGeom); group.Children.Add(textGeom); targetImage.Clip = group; } 结构上的where界限(并将其保留在Model上),则编辑的代码将被编译。 我会尝试减少一点并提交错误。

impl

playground