Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust &引用;“子类化”;锈病特征_Rust_Polymorphism_Traits - Fatal编程技术网

Rust &引用;“子类化”;锈病特征

Rust &引用;“子类化”;锈病特征,rust,polymorphism,traits,Rust,Polymorphism,Traits,我有一种情况,我的几个结构应该实现多个trait,但它们都至少实现了一个共同的trait。当我得到这些结构的混合包时,我希望将它们都视为共同特征:将它们作为键入该特征的方法参数传递,将它们存储在为该特征键入的集合中,等等 我还不知道怎么做。下面是一些代码,我尝试按照此处建议的方式执行,但未能编译: trait ThingWithKeys { fn use_keys (&self) -> String; } ////// trait CorrectionsOfficer

我有一种情况,我的几个结构应该实现多个trait,但它们都至少实现了一个共同的trait。当我得到这些结构的混合包时,我希望将它们都视为共同特征:将它们作为键入该特征的方法参数传递,将它们存储在为该特征键入的集合中,等等

我还不知道怎么做。下面是一些代码,我尝试按照此处建议的方式执行,但未能编译:

trait ThingWithKeys {
    fn use_keys (&self) -> String;
}

//////

trait CorrectionsOfficer {
    fn hitch_up_pants (&self) -> String;
}

trait CorrectionsOfficerWithKeys: ThingWithKeys + CorrectionsOfficer {}

struct CorrectionsOfficerReal {}

impl ThingWithKeys for CorrectionsOfficerReal {
    fn use_keys (&self) -> String {
        String::from ("Clank, clank")
    }
}

impl CorrectionsOfficer for CorrectionsOfficerReal {
    fn hitch_up_pants (&self) -> String {
        String::from ("Grunt")
    }
}

impl <T: ThingWithKeys + CorrectionsOfficer> CorrectionsOfficerWithKeys for T {}

//////

trait Piano {
    fn close_lid (&self) -> String;
}

trait PianoWithKeys: Piano + ThingWithKeys {}

struct PianoReal {}

impl ThingWithKeys for PianoReal {
    fn use_keys (&self) -> String {
        String::from ("Tinkle, tinkle")
    }
}

impl Piano for PianoReal {
    fn close_lid (&self) -> String {
        String::from ("Bang!")
    }
}

impl <T: ThingWithKeys + Piano> PianoWithKeys for T {}

//////

trait Florida {
    fn hurricane (&self) -> String;
}

trait FloridaWithKeys: ThingWithKeys + Florida {}

struct FloridaReal {}

impl ThingWithKeys for FloridaReal {
    fn use_keys (&self) -> String {
        String::from ("Another margarita, please")
    }
}

impl Florida for FloridaReal {
    fn hurricane (&self) -> String {
        String::from ("Ho-hum...")
    }
}

impl <T: ThingWithKeys + Florida> FloridaWithKeys for T {}

//////

fn main() {
    let corrections_officer_ref: &CorrectionsOfficerWithKeys = &CorrectionsOfficerReal {};
    let piano_ref: &PianoWithKeys = &PianoReal {};
    let florida_ref: &FloridaWithKeys = &FloridaReal {};

    use_keys (corrections_officer_ref);
    use_keys (piano_ref);
    use_keys (florida_ref);
}

fn use_keys (thing_with_keys: &ThingWithKeys) {
    println! ("{}", thing_with_keys.use_keys ());
}

本质上,它仍然无法在XxxWithKeys实现中找到ThingWithKeys实现。

Rust中的特征继承不同于OOP继承。特质继承只是一种指定需求的方法<代码>特征B:A并不意味着如果一个类型实现了
B
,它将自动实现
A
;这意味着如果一个类型实现
B
,它必须实现
a
。这也意味着如果实现了
B
,则必须单独实现
A

例如,

trait A {}
trait B: A {}

struct S;

impl B for S {}

// Commenting this line will result in a "trait bound unsatisfied" error
impl A for S {}

fn main() {
    let _x: &B = &S;
}
但是,如果希望某个类型在实现
a
B
时自动实现
C
(从而避免手动实现该类型的
C
),则可以使用泛型
impl

impl<T: A + B> C for T {}
泛型方法也适用于类型引用(非特征对象)


同时检查:

圣诞快乐!我刚才在操场上试过,但似乎不起作用。也许我做错了。我会告诉你我做了什么,但是StackOverflow对注释中的代码格式做了可怕的事情。无论如何,结果是它仍然抱怨XxxWithKeys不是ThingWithKeys,不能传递到use\u keys方法中。(我知道:我会编辑原来的问题,把我的新代码放进去。)哇。实际上,我刚刚发现了通用方法签名的问题,并收到了关于size的投诉,但我在一百万年内从未想过尝试+?size,因为它是一个引用,引用的大小都是一样的。你有没有理由需要+?大小,或者这只是一个你必须记住的魔法咒语?(顺便说一句,谢谢——现在可以正常工作了。)这是因为泛型类型参数在默认情况下是
大小的。然而,特质类型并非如此。要允许类型参数接受未大小(trait)类型,必须添加未大小(
?Sized
)绑定。此外,类型参数绑定到引用的类型,而不是引用本身。
impl<T: Florida + ThingWithKeys> FloridaWithKeys for T {}
fn use_keys<T: ThingWithKeys + ?Sized>(thing_with_keys: &T) {
    println! ("{}", thing_with_keys.use_keys ());
}