【问题标题】:No trait inferred from structs that implement a trait in Rust?没有从实现 Rust 特征的结构推断出特征?
【发布时间】:2021-01-25 12:24:50
【问题描述】:

我有 2 个结构,都实现了一个 trait:

pub trait TFilter {
    fn getText(&self) -> String;
}

pub struct CommentFilter {
    comment: String
}

impl TFilter for CommentFilter {
    fn getText(&self) -> String {
        return self.comment;
    }
}

impl CommentFilter {
    pub fn from_text(context: &Context, text: String) -> Self {
        return CommentFilter {
            comment: text
        }
    }
}

// ---

pub struct RegExpFilter {
    text: String
}

impl RegExpFilter {
    pub fn from_text(context: &Context, text: String) -> Self {
        return RegExpFilter {
            text
        }
    }
}

impl TFilter for RegExpFilter {
    fn getText(&self) -> String {
        return self.text
    }
}



但是在尝试编译代码时:

      let filter: dyn TFilter = if text.chars().nth(0).unwrap() == '!' {
                CommentFilter::from_text(context, text);
            } else {
                RegExpFilter::from_text(context, "test".to_string());
            };

我得到一个错误:

error[E0308]: mismatched types
   --> src/filter.rs:113:20
    |
113 |               } else {
    |  ____________________^
114 | |                 RegExpFilter::from_text(context, "test".to_string());
115 | |             };
    | |_____________^ expected trait object `dyn filter::TFilter`, found `()`

怎么了?

PS1。我发现 ; 真的很受伤,但现在我明白了:

预期的特征对象dyn filter::TFilter,找到结构filter::CommentFilter

它不能检测到他们实际实现了这个特征吗?

PS2。我必须明确指定: dyn TFilter,否则编译器会从第一个if 分支推断它并检测为CommentFilter(这显然不适用于负分支)。

【问题讨论】:

    标签: struct rust traits


    【解决方案1】:

    尝试不使用分号:

          let filter: dyn TFilter = if text.chars().nth(0).unwrap() == '!' {
                CommentFilter::from_text(context, text)
            } else {
                RegExpFilter::from_text(context, "test".to_string())
            };
    

    【讨论】:

    • 是的,谢谢。我已经更新了我的问题,你能看看下面的编译错误吗?
    • 你不能有一个“裸体”dyn Trait 对象,因为它们没有大小。你必须把它们包装在一个盒子里。
    【解决方案2】:

    由于编译器不知道TFilter 的大小,您需要将其存储在包裹在这样一个 Box 中的堆上:

          let filter: Box<dyn TFilter> = if text.chars().nth(0).unwrap() == '!' {
                Box::new(CommentFilter::from_text(context, text))
            } else {
                Box::new(RegExpFilter::from_text(context, "test".to_string()))
            };
    

    【讨论】:

    • 我建议将此整合到您的其他答案中。
    • 我发现错误消息非常具有误导性,因为它与强制转换无关......
    猜你喜欢
    • 2023-03-29
    • 1970-01-01
    • 2021-01-01
    • 2020-12-24
    • 2016-05-29
    • 2022-12-07
    • 2021-07-18
    • 2019-12-08
    • 2020-08-15
    相关资源
    最近更新 更多