对结构的复杂特征要求 [英] Complex trait requirements on struct

查看:34
本文介绍了对结构的复杂特征要求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我设置了一个相当复杂的特征,但我在整理这些部分时遇到了麻烦.现在大概是这样的:

I have a fairly complex trait set up and I'm having trouble lining the pieces up. Right now it looks roughly like this:

/// 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 //
}

现在我希望能够允许实现 OptimAlg​​orithm 的结构成为实现 Optimizable 的结构中的一个字段.这看起来像这样:

Now I want to be able to allow a struct implementing OptimAlgorithm to be a field in a struct implementing Optimizable. This would look something like this:

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

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

这不起作用,因为结构上的 Self 引用是无意义的.我尝试为 OptimAlg​​orithm 使用关联类型,但我需要算法在模型上是通用的,所以这不起作用.是否有我遗漏的魔法语法,或者这需要大修吗?

This doesn't work as the Self reference on the struct is nonsense. I tried using associated types for OptimAlgorithm but I need the algorithms to be generic over the models so this doesn't work. Is there a magic syntax I'm missing or does this need an overhaul?

编辑 --

这是一个最小示例,它显示了错误 E0275,如中所述史蒂文的回答.它更接近我的源代码,但不那么混乱.

Here's a minimal example which shows error E0275 as described in Steven's answer. It's a little closer to my source code but less messy.

推荐答案

只需使用 Model 而不是 Self.Self 仅在需要能够引用实现 trait 的具体类型的 trait 中才真正有用.在这里,具体类型总是Model.

Just use Model<A> instead of Self. Self is only really useful in traits where one needs to be able to refer to the concrete type implementing the trait. Here, the concrete type is always 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 = ();
}

<小时>

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


In response to your updated code, the lifetime appears to be giving rust trouble. It appears you can make this work by using a higher-ranked lifetime but I don't know why.

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]);
}

这篇关于对结构的复杂特征要求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆