Rust 锈菌框:一种包含普通性状的单一性状

Rust 锈菌框:一种包含普通性状的单一性状,rust,Rust,我所处的情况是,我希望一些对象实现一个trait,比如“Base”,而其他一些对象将实现一个trait“Super”。Super-trait还必须是T:Base的泛型,这样我就可以根据它所专用的Base自动实现Super的某些部分。现在,对于下面这个简单的例子,这似乎可以很好地工作 trait Base { fn say_hi() -> &'static str; } struct BaseOne {} struct BaseTwo {} impl Base for B

我所处的情况是,我希望一些对象实现一个trait,比如“Base”,而其他一些对象将实现一个trait“Super”。Super-trait还必须是
T:Base
的泛型,这样我就可以根据它所专用的Base自动实现Super的某些部分。现在,对于下面这个简单的例子,这似乎可以很好地工作

trait Base {
    fn say_hi() -> &'static str;
}

struct BaseOne {}
struct BaseTwo {}

impl Base for BaseOne {
    fn say_hi() -> &'static str {
        "hi!"
    }
}

impl Base for BaseTwo {
    fn say_hi() -> &'static str {
        "hello!"
    }
}

trait Super<T: Base> {
    fn say_hi(&self) -> &'static str {
        T::say_hi()
    }
}

struct SuperOne;
struct SuperTwo;

impl Super<BaseOne> for SuperOne {}
impl Super<BaseTwo> for SuperTwo {}
这有点奇怪,因为在我看来,我已经为所有人实现了AnySuper
Super
。所以我的问题是,我到底是做错了什么,还是我的语法有问题


另外,如果有人想玩的话,我已经用这个代码建立了一个游乐场。

我想有些奇怪的事情正在发生,因为你正在经历两层特质对象间接定向,即从具体的
。当然,Rust可以处理第一种情况,就像我们一直在做的那样,但第二种情况我没见过

但是,从它的声音来看,您想说“
AnySuper
Super
用于任何
T
”时都被实现,而您在代码中所写的是“
AnySuper
是为一种叫做
dyn Super
的有趣特性对象类型实现的”。让我们试着编写一个实际的总体实现

impl<S, T> AnySuper for S where S : Super<T>, T : Base
现在Rust将愉快地接受你的
AnySuper
向量

工作代码示例:

trait Base {
    fn say_hi() -> &'static str;
}

struct BaseOne {}
struct BaseTwo {}

impl Base for BaseOne {
    fn say_hi() -> &'static str {
        "hi!"
    }
}

impl Base for BaseTwo {
    fn say_hi() -> &'static str {
        "hello!"
    }
}

trait Super {
    type T : Base;
    fn say_hi(&self) -> &'static str {
        Self::T::say_hi()
    }
}

struct SuperOne;
struct SuperTwo;

impl Super for SuperOne {
    type T = BaseOne;
}
impl Super for SuperTwo {
    type T = BaseTwo;
}

trait AnySuper {
    fn say_hi(&self) -> &'static str;
}

impl<S> AnySuper for S where S : Super, S::T : Base {
    fn say_hi(&self) -> &'static str {
        Super::say_hi(self)
    }
}

fn main() {
    let one = Box::new(SuperOne);
    let two = Box::new(SuperTwo);
    
    let mut my_vec: Vec<Box<dyn AnySuper>> = Vec::new();
    
    my_vec.push(one);
    my_vec.push(two);
    
    println!("Success!");
}
特征库{
fn say_hi()->&'static str;
}
结构BaseOne{}
结构BaseTwo{}
BaseOne的impl Base{
fn说_hi()->&'{
“嗨!”
}
}
Base2的impl基{
fn说_hi()->&'{
“你好!”
}
}
性状超级{
T型:基底;
fn说“嗨(&self)->&”{
Self::T::说你好()
}
}
结构超素;
结构超二;
SuperOne的impl Super{
T型=基本型;
}
超级2的impl Super{
T型=基准2;
}
特徵AnySuper{
fn说_hi(&self)->&'static str;
}
S的impl AnySuper,其中S:Super,S::T:Base{
fn说“嗨(&self)->&”{
超级:说你好(自我)
}
}
fn main(){
设一=Box::new(SuperOne);
设两个=Box::new(SuperTwo);
让mut my_vec:vec=vec::new();
我的车推(一);
我的车推(两个);
println!(“成功!”);
}

谢谢,这个答案太棒了!在侧节点上,没有一种简单的方法可以自动将所有函数调用从AnySuper映射到Super,即使这两个特征具有相同的签名,对吗?正确。尽管这两个
say_hi
函数共享一个名称和签名,但就Rust而言,它们是不相关的,因为它们生活在不同的特征中。
error[E0277]: the trait bound `SuperOne: AnySuper` is not satisfied
  --> src/main.rs:52:17
   |
52 |     my_vec.push(one);
   |                 ^^^ the trait `AnySuper` is not implemented for `SuperOne`
   |
   = note: required for the cast to the object type `dyn AnySuper`

error[E0277]: the trait bound `SuperTwo: AnySuper` is not satisfied
  --> src/main.rs:53:17
   |
53 |     my_vec.push(two);
   |                 ^^^ the trait `AnySuper` is not implemented for `SuperTwo`
   |
   = note: required for the cast to the object type `dyn AnySuper`
impl<S, T> AnySuper for S where S : Super<T>, T : Base
error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates
  --> src/main.rs:36:9
   |
36 | impl<S, T> AnySuper for S where S : Super<T>, T : Base {
   |         ^ unconstrained type parameter
trait Super {
    type T : Base;
    fn say_hi(&self) -> &'static str {
        Self::T::say_hi()
    }
}

impl Super for SuperOne {
    type T = BaseOne;
}
impl Super for SuperTwo {
    type T = BaseTwo;
}

impl<S> AnySuper for S where S : Super, S::T : Base {
    fn say_hi(&self) -> &'static str {
        Super::say_hi(self)
    }
}
trait Base {
    fn say_hi() -> &'static str;
}

struct BaseOne {}
struct BaseTwo {}

impl Base for BaseOne {
    fn say_hi() -> &'static str {
        "hi!"
    }
}

impl Base for BaseTwo {
    fn say_hi() -> &'static str {
        "hello!"
    }
}

trait Super {
    type T : Base;
    fn say_hi(&self) -> &'static str {
        Self::T::say_hi()
    }
}

struct SuperOne;
struct SuperTwo;

impl Super for SuperOne {
    type T = BaseOne;
}
impl Super for SuperTwo {
    type T = BaseTwo;
}

trait AnySuper {
    fn say_hi(&self) -> &'static str;
}

impl<S> AnySuper for S where S : Super, S::T : Base {
    fn say_hi(&self) -> &'static str {
        Super::say_hi(self)
    }
}

fn main() {
    let one = Box::new(SuperOne);
    let two = Box::new(SuperTwo);
    
    let mut my_vec: Vec<Box<dyn AnySuper>> = Vec::new();
    
    my_vec.push(one);
    my_vec.push(two);
    
    println!("Success!");
}