预期类型`Box< ...>`,从工厂返回一个盒装特征对象时发现类型为`()`

时间:2016-07-14 21:44:21

标签: rust traits

这个问题显示我是一个新手(来自Java并且现在研究Rust三天了)。在网上搜索,我发现很多人都在问同一个问题,我确实看到答案说这不是使用特征的方法,但不知怎的,我不知道如何解决我的问题。

我想连接两个不同的stdin-stdout协议。它们在某种程度上是不同的,但它们都以它们的协议名称开头。所以我想动态选择我应该使用哪两种协议的实现。

我尝试了以下内容:

use std::io;
use std::io::prelude::*;

trait Protocol {
    fn parse(&self);
}

pub struct Abc {}
pub struct Xyz {}

impl Protocol for Abc {
    fn parse(&self) {
        println!("Hello to the BEGINNING of the alphabet");
    }
}

impl Protocol for Xyz {
    fn parse(&self) {
        println!("Hello to the END of the alphabet");
    }
}

fn get_protocol(line: &str) -> Box<Protocol + 'static> {
    if line.starts_with("Abc") {
        return Box::new(Abc {});
    }

    if line.starts_with("Xyz") {  // this gives error E0308, mismatched types
        return Box::new(Xyz {});
    }
}

fn main() {
    let stdin = io::stdin();

    // TODO: loop
    for line in stdin.lock().lines() {
        let line = line.unwrap();
        let protocol = get_protocol(&line);
        protocol.parse();
    }
}

如果可以,我可以打电话

回声“Abc”| ./demo_parser

但正如评论中所述,我因类型不匹配而收到错误。我已经添加了Box<..>,然后添加了'static(在网络上找到了这样的示例)。我找到了另一个使用~运算符的示例,但这对我来说不够具体。

我可以让这个例子有效吗,还是认为Java太多了?但是,我怎样才能解决我的问题?

感谢您的帮助。被引用为重复的问题对我有帮助。但是,它只是帮助了我几次读数后,由于这个问题有关于字符串的评论,我认为它不适用于我的问题。但确实如此,因为这可能对其他人有帮助,这里是我修改过的代码:

use std::io;
use std::io::prelude::*;

trait Protocol {
    fn parse(&self);
}

pub struct Abc {}
pub struct Xyz {}
pub struct Unknown {}

impl Protocol for Abc {
    fn parse(&self) {
        println!("Hello to the BEGINNING of the alphabet");
    }
}

impl Protocol for Xyz {
    fn parse(&self) {
        println!("Hello to the END of the alphabet");
    }
}

impl Protocol for Unknown {
    fn parse(&self) {
        panic!("using protocol Unknown!");
    }
 }

fn get_protocol(line: &str) -> Box<Protocol + 'static> {

    if line.starts_with("Abc") {
        return Box::new(Abc {});
    }

    if line.starts_with("Xyz") {
        return Box::new(Xyz {});
    }

    return Box::new(Unknown {});
}

fn main() {

    let stdin = io::stdin();

    // TODO: loop
    for line in stdin.lock().lines() {
        let line = line.unwrap();
        let protocol = get_protocol(&line);
        protocol.parse();
    }
}

此代码有效,但与其中一条评论相反,它仍然需要“返回”,否则我会

并非所有控制路径都返回值[E0269]

无论如何,感谢大家的耐心帮助。

0 个答案:

没有答案