对结构的复杂特征要求 [英] Complex trait requirements on struct
问题描述
我设置了一个相当复杂的特征,但我在整理这些部分时遇到了麻烦.现在大概是这样的:
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 //
}
现在我希望能够允许实现 OptimAlgorithm
的结构成为实现 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
引用是无意义的.我尝试为 OptimAlgorithm
使用关联类型,但我需要算法在模型上是通用的,所以这不起作用.是否有我遗漏的魔法语法,或者这需要大修吗?
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屋!