简体   繁体   English

我可以有可选的特征范围吗?

[英]Can I have optional trait bounds?

Given a trait that models a conditional probability distribution: 给定一个模拟条件概率分布的特征:

trait Distribution {
    type T;
    fn sample<U>(&self, x: U) -> Self::T;
}

I want to implement the trait for two structs, ConditionalNormal and MultivariateConditionalNormal which model a scalar and vector valued distribution respectively. 我想为两种结构(分别为标量和向量值分布建模)的ConditionalNormalMultivariateConditionalNormal实施特征。

Such implementations look like this: 这样的实现如下所示:

struct ConditionalNormal;

impl Distribution for ConditionalNormal {
    type T = f64;

    fn sample<U>(&self, x: U) -> Self::T {
        0.0
    }
}

struct MultivariateConditionalNormal;

impl Distribution for MultivariateConditionalNormal {
    type T = f64;

    fn sample<U>(&self, x: U) -> Self::T {
        0.0 + x[0]
    }
}

( playground ) 游乐场

However, the implementation for MultivariateConditionalNormal is invalid because the generic x[0] is not indexable. 但是, MultivariateConditionalNormal的实现无效,因为通用x[0]不可索引。 If I add the trait bounds std::ops::Index<usize> the implementation for ConditionalNormal is invalid, because a scalar f64 is not indexable. 如果我添加特征边界std::ops::Index<usize> ,则ConditionalNormal的实现无效,因为标量f64不可索引。

I have heard that eg the Sized trait accepts optional trait bounds via ?Sized ; 我听说,例如Sized特质通过?Sized接受可选的特征范围; can I do something similar? 我可以做类似的事情吗? Is there any way to resolve this problem? 有什么办法解决这个问题?

You can change the definition of the trait to 您可以将特征的定义更改为

trait Distribution<U> {
    type T;
    fn sample(&self, x: U) -> Self::T;
}

This allows you to implement it on various types with different trait bounds. 这使您可以在具有不同特征范围的各种类型上实现它。

impl<U> Distribution<U> for ConditionalNormal {
    // ...
}

impl<U> Distribution<U> for MultivariateConditionalNormal
where
    U: std::ops::Index<usize, Output = f64>,
{
    // ...
}

Playground 操场

You can add a new trait to specify what are the capabilities of U : 您可以添加一个新特征来指定U的功能:

trait Distribution {
    type T;
    fn sample<U>(&self, x: U) -> Self::T
    where
        U: Samplable;
}

struct ConditionalNormal;

impl Distribution for ConditionalNormal {
    type T = f64;

    fn sample<U>(&self, x: U) -> Self::T
    where
        U: Samplable,
    {
        0.0.value()
    }
}

struct MultivariateConditionalNormal;

impl Distribution for MultivariateConditionalNormal {
    type T = f64;

    fn sample<U>(&self, x: U) -> Self::T
    where
        U: Samplable,
    {
        0.0 + x.value()
    }
}

trait Samplable {
    fn value(&self) -> f64;
}

impl Samplable for f64 {
    fn value(&self) -> f64 {
        *self
    }
}

impl Samplable for Vec<f64> {
    fn value(&self) -> f64 {
        self[0]
    }
}

fn main() {}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 是否可以为特征提供可选的泛型类型? - Is it possible to have an optional generic type for a trait? Rust 特征边界与类型 - Rust trait bounds with types 为什么忽略“按特征发送”实现的特征范围? - Why are trait bounds for Send on trait implementations ignored? 如何对包含不同类型的链表进行静态调度,所有类型都实现了一个特征? - How can I have static dispatch for a linked list containing different types all implementing a trait? 如何在Scala上使用Trait创建类? - How can I create A Class with Trait On Scala? 无法将trait边界添加到结构的成员 - Unable to add trait bounds to member of a struct 如何消除特征对象边界中关联类型的歧义? - How to disambiguate associated types in trait object bounds? 如何在 rust 宏中扩展多个特征边界? - How are multiple trait bounds expanded in a rust macro? 如果我在 struct 块中定义了 Rust 代码中的每个 impl 块,是否需要手动重写它的所有特征边界? - Do I need to manually rewrite all the trait bounds for every impl block in my Rust code if I defined it in struct block? 如果已经将特征边界添加到另一个impl块,为什么还要在其上添加特征边界? - Why do I need to add trait bounds on impl blocks if I've already added them to another impl block?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM