generics - 如何限制 Rust 中特征的通用实现?

标签 generics rust

作为学习 Rust 的借口,我正在研究遗传算法的代码,以及稍后的遗传编程。

我声明了一个变异操作的特征:

pub trait Mutator<IndvidualType> {
    fn mutate(&self, individual: &IndvidualType) -> IndvidualType;
}

为每个 IndividualType 实现特征很容易,但我想要更通用的东西,一个对每个列表(向量)类型基因组都很常见的特征,比如:

pub trait HasVectorGenome<IndividualType, BaseType>  {
    fn new_from_vec(genome: Vec<BaseType>) -> IndvidualType;
    fn get_vec(&self) -> Vec<BaseType>;
}

我想要一个通用的更改器(mutator),它能够变异每个 HasVectorGenomeBaseType 实现 Rand(为了能够生成一个新的随机值)。像这样的东西:

struct GeneralMutator;

impl<B, T> Mutator<T> for GeneralMutator
    where T: HasVectorGenome<T, B>,
          B: Rand
{
    fn mutate(&self, individual: &T) -> T {
        let genome: Vec<B> = individual.get_vec();
        genome[0] = rand::random::<B>();
        T::new_from_vec(genome)
    }
}

我遇到了错误类型参数 `B` 不受 impl 特征、自身类型或谓词的约束,我无法编译。我不知道如何正确表达这一点。

最佳答案

我已经放了这段代码的完整工作版本 on the playground (除了我删掉了随机部分)。

首先,我从 HasVectorGenome 中删除了 IndividualType 参数。这只是实现特征的类型,并且您对特征的定义与此不一致(new_from_vec 返回 IndividualTypeget_vec 消耗 self )。

其次,我将 BaseType 设为关联类型,这意味着任何单独的类型都有一个唯一的基类型。这在技术上是一个限制,但在大多数情况下,您不需要灵 active ,它使类型更简单(实际上是消除您看到的错误所需的主要更改)。所以现在的特征是:

pub trait HasVectorGenome  {
    type BaseType;
    fn new_from_vec(genome: Vec<Self::BaseType>) -> Self;
    fn get_vec(&self) -> Vec<Self::BaseType>;
}

然后,我调整了 GeneralMutator 实现的 where 子句:

impl<T> Mutator<T> for GeneralMutator
  where T: HasVectorGenome,
        T::BaseType : Rand

关于generics - 如何限制 Rust 中特征的通用实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35525505/

相关文章:

generics - 泛型参数丢失信息

multithreading - 如何将对堆栈变量的引用传递给线程?

string - 使用 `pop3::POP3Stream::connect` 连接到给定 `host` 的运行时?

pattern-matching - 从 Options 和 Results 中移除 unwrap 调用而不引入双重缩进的匹配语句

c# - 在 C# 中转换为泛型类型

子类化时Java泛型不兼容的类型

java - 设计一个在数组中存储可比对象的通用类

c# - 我知道 typeof(T) 但编译器不知道。怎么修?

rust - 如何正确处理复杂的递归生命周期?

rust - 如何将 Base58 编码的数据转换为 Vec<u8> 然后转换为字符串?