Cargo 测试在保存文件后警告未使用的代码

Cargo test warns for unused code after saving file

我开始掌握 Rust 模块,但我在板条箱的 src 目录中有以下内容。如果我做了一个小修改(添加一些空格或重命名测试函数),保存然后立即 运行 cargo test 我收到一个未使用函数的警告,但是如果我等几秒钟,并且 运行 再次出现,它 运行 没有任何警告。

lib.rs

mod greet;

#[test]
pub fn it_greets_the_world_correctly() {
    assert_eq!("Hello, world!", greet::greet("world"));
}

greet.rs

pub fn greet(name: &str) -> String {
    format!("Hello, {}!", name)
}

但是当我 运行 cargo test 我得到以下信息:

$ cargo test
   Compiling hello v0.1.0 (file:///F:/workspace/hello_rust)
src\greet.rs:1:1: 3:2 warning: function is never used: `greet`, #[warn(dead_code)] on by default
src\greet.rs:1 pub fn greet (name: &str) -> String {
src\greet.rs:2   format!("Hello, {}!", name)
src\greet.rs:3 }
     Running target\debug\hello-111b9369d8889475.exe

running 1 test
test it_greets_the_world_correctly ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured

   Doc-tests hello

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured

然后几秒钟后...

$ cargo test
     Running target\debug\hello-111b9369d8889475.exe

running 1 test
test it_greets_the_world_correctly ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured

   Doc-tests hello

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured

我对抑制警告不感兴趣,我很好奇 Rust 怎么可能认为函数在明显被调用时没有被使用,因为测试在两个 运行 中都通过了测试。

使用cargo test --verbose会给你一些答案。

首先,cargo test 将为 lib--crate-type lib 编译所有内容。这就是导致您发出警告的原因。 greet::greet 实际上并未在您的库代码中调用。

接下来,cargo test 将 运行 rustc --crate-type lib --test 作为一个单独的步骤针对库。这个确实调用了greet::greet,所以你没有收到警告。

现在,如果您再次触摸文件并将测试更改为:

assert_eq!("Hello, world!", "Hello, world!");

你会注意到你收到了两个关于同一件事的警告...因为这两个步骤都没有引用 greet::greet 函数(库没有调用它..测试也没有叫它)。

我认为这是一个有效的警告,并且是您想要的:警告是说您有一个方法未在您的库代码中调用.. 即使测试调用它。我认为,在更大的代码库中,您会希望收到警告并清理您的测试,这些测试现在正在测试主代码库中未使用的函数。

仔细检查输出:

$ cargo test
   Compiling hello v0.1.0 (file:///F:/workspace/hello_rust)
     Running target\debug\hello-111b9369d8889475.exe
$ cargo test
     Running target\debug\hello-111b9369d8889475.exe

当您第二次执行 cargo test 时,您的代码没有任何变化。因为什么都没有改变,代码不需要重新编译。

编译器警告如未使用的函数仅在编译器 运行s 时生成。如果编译器不 运行,则不会有任何警告。

更改代码将触发重新编译。


后续的问题是,为什么它认为该功能未被使用? 涵盖了这一点。即使该函数被标记为 pub,它所在的 模块 也不是 public。这意味着不可能在库外调用该函数。由于库中没有调用它,因此未使用。