我开始掌握Rust模块,但是我在板条箱的src
目录中有以下内容。如果我进行了一个小的修改(添加一些空格或重命名测试功能),请保存,然后立即运行cargo test
,我会警告未使用的功能,但是如果我等待几秒钟,然后再次运行它,它将不用警告而运行。
lib.rs
mod greet;
#[test]
pub fn it_greets_the_world_correctly() {
assert_eq!("Hello, world!", greet::greet("world"));
}
etch.rs
pub fn greet(name: &str) -> String {
format!("Hello, {}!", name)
}
但是当我运行cargo test
时,我会得到以下内容:
$ cargo test
Compiling hello v0.1.0 (file:///F:/workspace/hello_rust)
srcgreet.rs:1:1: 3:2 warning: function is never used: `greet`, #[warn(dead_code)] on by default
srcgreet.rs:1 pub fn greet (name: &str) -> String {
srcgreet.rs:2 format!("Hello, {}!", name)
srcgreet.rs:3 }
Running targetdebughello-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 targetdebughello-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
将使用--crate-type lib
编译lib
的所有内容。这就是引起您警告的原因。greet::greet
实际上并未在您的库代码中调用。
接下来,cargo test
将以单独的步骤运行rustc --crate-type lib --test
。这个 do 致电 greet::greet
,因此您没有任何警告。
现在,如果您再次触摸文件并将测试更改为此:
assert_eq!("Hello, world!", "Hello, world!");
您会注意到您会收到同一件事的两个警告...因为这两个步骤都不引用greet::greet
函数(库不调用..P>
我认为这是一个有效的警告,是您想要的:警告说您有一种在库代码中未调用的方法。即使测试调用它。我认为,在较大的代码库中,您希望被警告并清理您的测试,这些测试现在正在测试主要代码库中未使用的功能。
密切检查输出:
$ cargo test
Compiling hello v0.1.0 (file:///F:/workspace/hello_rust)
Running targetdebughello-111b9369d8889475.exe
$ cargo test
Running targetdebughello-111b9369d8889475.exe
第二次执行cargo test
时,代码没有任何更改。因为什么都没有改变,所以代码不需要重新编译。
诸如未使用功能之类的编译器警告仅在编译器运行时生成。如果编译器不运行,则不会有任何警告。
更改代码将触发重新编译。
后续问题是,为什么认为该功能未使用?西蒙·怀特海(Simon Whitehead)的答案涵盖了这一点。即使该函数标记为pub
,模块它不是公共的。这意味着不可能在库之外调用该功能。由于图书馆内没有打电话,因此未使用。