Ole*_*yba 2 generics traits rust
这是显示我的问题的抽象示例,从我尝试重构一些Rust代码并同时学习Rust中提取.
struct GenStruct<T> {
field: T,
}
trait Marker {}
trait Return {}
impl Marker for i32 {}
impl Marker for u32 {}
// actually implement `Return` for GenStruct<M: Marker>,
// but compiler don't recognize that
impl Return for GenStruct<i32> {}
impl Return for GenStruct<u32> {}
struct Fake;
trait Trait<M: Marker> {
type Ret: Return;
fn meth(m: M) -> Self::Ret;
}
impl<M: Marker> Trait<M> for Fake {
type Ret = GenStruct<M>;
fn meth(m: M) -> GenStruct<M> {
GenStruct { field: m }
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
error[E0277]: the trait bound `GenStruct<M>: Return` is not satisfied
--> src/lib.rs:23:17
|
23 | impl<M: Marker> Trait<M> for Fake {
| ^^^^^^^^ the trait `Return` is not implemented for `GenStruct<M>`
|
Run Code Online (Sandbox Code Playgroud)
编译器无法识别我实际Return为GenStruct<M>M所在的每个地方实现Marker.为了解决这个问题,我可以这样写:
trait Marker {
fn is_i32() -> bool;
}
trait Return {
fn ret();
}
impl Marker for i32 {
fn is_i32() -> bool {
true
}
}
impl Marker for u32 {
fn is_i32() -> bool {
false
}
}
// compiler is satisfied by such implementation
impl<M: Marker> Return for GenStruct<M> {
fn ret() {
if M::is_i32() {
} else {
}
}
}
Run Code Online (Sandbox Code Playgroud)
..或使用特质对象..
impl<M: Marker> Return for GenStruct<M> {}
trait Trait<'a, M: Marker + 'a> {
fn meth(m: M) -> Box<Return + 'a>;
}
impl<'a, M: Marker + 'a> Trait<'a, M> for Fake {
fn meth(m: M) -> Box<Return + 'a> {
Box::new(GenStruct { field: m })
}
}
Run Code Online (Sandbox Code Playgroud)
..但如果我使用特征对象,我不能写一个专门的Returnfor GenStruct<i32>和GenStruct<u32>.
我的问题是:能否GenStruct<M: Marker>认识到我确实实现了Return或者我的代码是不是惯用的Rust?如果我的代码不是惯用的,那么编写代码的正确方法是什么?
使用where子句,我们可以在泛型上添加一个额外的约束,impl以便它只适用于GenStruct<M>确实实现的情况Return.
impl<M: Marker> Trait<M> for Fake
where
GenStruct<M>: Return,
{
type Ret = GenStruct<M>;
fn meth(m: M) -> GenStruct<M> {
GenStruct { field: m }
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
720 次 |
| 最近记录: |