如何限制在Rust中的特征的通用实现? [英] How to restrict generic implementation of a trait in Rust?
问题描述
我声明了一个变异操作的特征:
pub trait Mutator< ; IndvidualType> {
fn mutate(& self,individual:& IndvidualType) - > IndvidualType;
}
对于每一个 IndividualType
,但我想要一些更一般的东西,这是每个列表(矢量)类型基因组常见的特征,如:
pub trait HasVectorGenome< IndividualType,BaseType> {
fn new_from_vec(基因组:Vec< BaseType>) - > IndvidualType;
fn get_vec(& self) - > VEC<碱基类型取代;
}
我想要一个通用的mutator,它能够将每个 HasVectorGenome
其中 BaseType
implements Rand
(为了能够生成新的随机值)。例如:
struct GeneralMutator;
impl< B,T>增变< T> for GeneralMutator
其中T:HasVectorGenome< T,B>,
B:Rand
{
fn mutate(& self,individual:& T) - > T {
let基因组:Vec< B> = individual.get_vec();
基因组[0] = rand :: random ::< B>();
T :: new_from_vec(genome)
}
}
我得到错误类型参数`B`不受impl特征,自我类型或谓词
的限制,我无法编译。我不知道如何正确表达这一点。
我已经把这段代码的完整工作版本上的https://play.rust-lang.org/?gist=9d66c3969ed377dd9314&version=stablerel =nofollow>(除了我将随机部分剔除)。
首先,我从 HasVectorGenome
中删除了 IndividualType
参数。这只是实现特征的类型,而你对特征的定义与此不一致( new_from_vec
返回 IndividualType
但是 get_vec
消费 Self
)。
第二,我做了 BaseType
一个关联类型,这意味着任何单个类型都有一个唯一的唯一基类型。这在技术上是一种限制,但在大多数情况下,您不需要灵活性,并且使类型更简单(实际上是摆脱错误所需的主要更改)。所以这个特性现在是:
pub trait HasVectorGenome {
type BaseType;
fn new_from_vec(基因组:Vec< Self :: BaseType>) - >自;
fn get_vec(& self) - > VEC<自::碱基类型取代;
}
然后,我调整了 GeneralMutator的where子句执行:
impl< T>增变< T> for GeneralMutator
其中T:HasVectorGenome,
T :: BaseType:Rand
As an excuse to learn Rust, I'm working on code for genetic algorithms, and genetic programming later.
I declared a trait for mutation operations:
pub trait Mutator<IndvidualType> {
fn mutate(&self, individual: &IndvidualType) -> IndvidualType;
}
It is easy to implement the trait for every single IndividualType
, but I want something more general, a trait which is common for every list (vector) type genome, something like:
pub trait HasVectorGenome<IndividualType, BaseType> {
fn new_from_vec(genome: Vec<BaseType>) -> IndvidualType;
fn get_vec(&self) -> Vec<BaseType>;
}
I want to have a generic mutator which is able to mutate every HasVectorGenome
whose BaseType
implements Rand
(in order to be able to generate a new random value). Something like:
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)
}
}
I've got the error the type parameter `B` is not constrained by the impl trait, self type, or predicates
, and I can't compile. I do not know how to express this correctly.
I've put a complete working version of this code on the playground (except that I stubbed out the random parts).
First, I removed the IndividualType
parameter from HasVectorGenome
. This is simply the type for which the trait is implemented, and your definition of the trait is inconsistent about this (new_from_vec
returns IndividualType
but get_vec
consumes Self
).
Second, I made BaseType
an associated type, meaning that there is a single unique base type for any individual type. This is technically a restriction, but in most circumstances you don't need the flexibility and it makes the types simpler (and is in fact the primary change needed to get rid of the error you're seeing). So the trait is now:
pub trait HasVectorGenome {
type BaseType;
fn new_from_vec(genome: Vec<Self::BaseType>) -> Self;
fn get_vec(&self) -> Vec<Self::BaseType>;
}
Then, I adjusted the where clause of the GeneralMutator
implementation:
impl<T> Mutator<T> for GeneralMutator
where T: HasVectorGenome,
T::BaseType : Rand
这篇关于如何限制在Rust中的特征的通用实现?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!