错误E0433 - 从测试访问模块时使用未声明的类型或模块

The*_*Cat 4 rust

作为Rust的第一个项目,我正在尝试创建一个行程编码库.

这是我的src/lib.rs(最初由货物创建):

#[cfg(test)]

mod rle;
mod tests {

    #[test]

    fn it_works() {
        let rle1 = rle::Rle {
            lengths: vec![1, 4, 2],
            values: vec![1, 2, 1],
        };
    }

}
Run Code Online (Sandbox Code Playgroud)

这是我的src/rle.rs:

pub struct Rle {
    lengths: Vec<i32>,
    values: Vec<i32>,
}
Run Code Online (Sandbox Code Playgroud)

使用这种布局,我得到了一个 error[E0433]: failed to resolve. Use of undeclared type or module 'rle'

我试图遵循Rust Docs中称为Crates and Modules的指南.

我究竟做错了什么?

如果布局不明显:

$ ls src
lib.rs rle.rs
Run Code Online (Sandbox Code Playgroud)

Mat*_* M. 5

您使用时出错#[cfg(test)].

Rust有两种应用属性的方法:

  • #[...] 适用于下一个项目
  • #![...] 适用于封闭物品

这意味着在这里,#[cfg(test)]应用于下一个item(mod rle;),因此只能在测试模式下编译.另一方面,您的tests模块将始终被编译.

因此,当不在测试模式下运行时,您有:

  • 没有rle模块
  • 一个tests模块指的是rle模块

修复很简单:移动属性使其适用于mod tests,而不是mod rle.


注意:

  • 如Chris所述,您还需要使用它super::rle来引用该rle模块.
  • 正如ljedrz所​​提到的,你还需要声明Rlepublic 的字段能够从文件外部命名它们(如果测试在同一个文件中,你不应该有这个问题).


lje*_*drz 5

您首先需要将Rle字段公开才能访问它们:

pub struct Rle {
    pub lengths: Vec<i32>,
    pub values: Vec<i32>,
}
Run Code Online (Sandbox Code Playgroud)

然后,在lib.rs文件中您应该像这样使用它:

mod rle; // you probably don't want #[cfg(test)] to apply to rle

#[cfg(test)] // this makes the tests module run only during cargo test
mod tests {
    use super::rle::Rle; // now Rle is applicable in the tests module

    #[test]
    fn it_works() {
        let rle1 = Rle {
            lengths: vec![1, 4, 2],
            values: vec![1, 2, 1],
        };
    }

}
Run Code Online (Sandbox Code Playgroud)

请注意,我改为let rle1 = rle::Rle {let rle1 = Rle {因为我导入的super::rle::Rle不仅仅是super::rle.

这编译没有问题。