作为学习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能够改变其HasVectorGenome
实现BaseType
的每个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)
}
}
我收到错误the type parameter `B` is not constrained by the impl trait, self type, or predicates
,我无法编译。我不知道如何正确表达这一点。
答案 0 :(得分:4)
我已经提供了此代码on the playground的完整工作版本(除了我删除了随机部分)。
首先,我从IndividualType
中删除了HasVectorGenome
参数。这只是实现特征的类型,并且您对特征的定义与此不一致(new_from_vec
返回IndividualType
但get_vec
消耗Self
)。
其次,我将BaseType
设为关联类型,这意味着任何单个类型都有一个唯一的基本类型。这在技术上是一种限制,但在大多数情况下,你不需要灵活性,它使类型更简单(实际上是摆脱你所看到的错误所需的主要变化)。所以现在的特点是:
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