首页 > 解决方案 > 如何正确使用与其实现分开的文件中的特征

问题描述

尝试将单独文件中定义的特征用于实现时,我有点头疼,并希望有人能指出我哪里出错了。

我的文件结构是这样的

main.rs
file1.rs
thing.rs

main.rs 的内容

mod file1;
mod thing;

fn main() {
    let item : Box<dyn file1::Trait1> = Box::new(thing::Thing {});
}

文件1.rs

pub trait Trait1 {    
}

东西.rs

mod file1 {
    include!("file1.rs");
}

pub struct Thing {    
}

impl file1::Trait1 for Thing {    
}

编译时的错误是:

error[E0277]: the trait bound `thing::Thing: file1::Trait1` is not satisfied
 --> src/main.rs:9:41
  |
9 |     let item : Box<dyn file1::Trait1> = Box::new(thing::Thing {});
  |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `file1::Trait1` is not implemented for `thing::Thing`
  |
  = note: required for the cast to the object type `dyn file1::Trait1`

据我所知, file1::Trait1 已实现。如果没有,我实际实施了什么?

标签: rustmoduletraitsimplementation

解决方案


mod file1 {
    include!("file1.rs");
}

通过将其写入thing.rs,您创建了一个模块 ,thing::file1它与顶级模块 不同file1。因此,您有两个不同版本的特征,thing::file1::Trait1并且file1::Trait1.

这几乎从来都不是正确的事情。作为一般原则,每个.rs文件(除了main.rslib.rs和其他 crate 根文件)都应该只有一个mod声明

从 中删除上述代码thing.rs,并使用use代替mod,或完全限定路径:

use crate::file1;
...
impl file1::Trait1 for Thing {
    ...

或者

use crate::file1::Trait1;
...
impl Trait1 for Thing {
    ...

或者

impl crate::file1::Trait1 for Thing {
    ...

通常,mod 定义一个模块,并将use 项目带入范围。每个模块只写mod一次,use在任何你想引用该模块的地方。


推荐阅读