我开始将我的一个项目的代码分组到模块文件中。我在这些模块中遇到了很多关于函数未使用代码的警告,但实际上使用了这些函数(在模块中私有)。
来自my project的示例:
// ...
// Line 46:
fn calc_p(word: &str, dict: &Dictionary) -> f32
{
if !dict.contains_key(word) {
return 0.0;
}
let total: u32 = dict.values().sum();
dict[word] as f32 / total as f32
}
...
但at line 13 in the same file,明确使用该功能的同一模块:
// ...
pub fn suggest_corrections(to_be_corrected: &str, dict: &Dictionary) -> Vec<(f32, String)>
{
let candidates = create_candidates(to_be_corrected, dict);
let mut weighted_candidates = candidates
.into_iter()
.map(|w| (calc_p(&w, dict), w)) // Line 13 - calc_p used here
.collect::<Vec<_>>();
weighted_candidates.sort_by(|a, b| b.partial_cmp(a).unwrap());
weighted_candidates
}
// ...
然而我得到了编译器警告:
warning: function is never used: `calc_p`, #[warn(dead_code)] on by default
--> src/spellcheck/corrections.rs:46:1
|
46 | fn calc_p(word: &str, dict: &Dictionary) -> f32
| _^ starting here...
47 | | {
48 | | if !dict.contains_key(word) {
49 | | return 0.0;
50 | | }
51 | |
52 | | let total: u32 = dict.values().sum();
53 | | dict[word] as f32 / total as f32
54 | | }
| |_^ ...ending here
我想也许是因为模块corrections
不公开,但我marked the module as public仍然得到同样的警告。
我尝试使用the playground重现行为,但是如果模块在同一个文件中定义,它似乎可以工作。在a TravisCI build期间,我也会收到警告。
为什么功能被标记为未使用,尽管它实际上在同一模块的同一文件中使用?
我正在使用Rust 1.15 / 1.16。
答案 0 :(得分:3)
为什么功能被标记为未使用,尽管它实际上在同一模块的同一文件中使用?
因为未使用的代码是传递计算,并且无法从包外调用调用该函数的代码。编译器在这里是正确的。
我看到的第一个错误是:
warning: static item is never used: `ALPHABET`, #[warn(dead_code)] on by default
--> src/spellcheck/edits.rs:3:1
这被定义为:
<强>的src /拼写检查/ edits.rs 强>
static ALPHABET : &'static str = "abcdefghijklmnopqrstuvwxyz";
所以它不公开,只能在模块内部使用。
来自replaces
和inserts
。这两个都来自edits1
,一个公共职能部门。包含它的模块(edits
)是否公开?
<强>的src /拼写检查/ mod.rs 强>
mod edits;
pub mod corrections;
pub mod dictionary;
不,不是。那么调用edits1
的位置是什么? kodecheck_spellcheck::spellcheck::corrections::create_candidates
,非公共职能。这由公共模块suggest_corrections
内的公共函数corrections
调用。
让我们查看树......
<强>的src / lib-spellcheck.rs 强>
// @FIXME do we really need this here or move to sub-modules?
#[macro_use]
extern crate nom;
extern crate regex;
mod spellcheck;
阿。无论出于何种原因,您已决定在包中引入完全嵌套的私有模块spellcheck
(这就是为什么之前的完整路径为kodecheck_spellcheck::spellcheck::corrections::create_candidates
)。
据此,我们可以看到无法从包装箱外部访问kodecheck_spellcheck::spellcheck
;它不是pub
。
让我们创建一个使用包的示例。这是查看它是否真实并且您可以轻松测试自己的最佳方式:
<强>实例/ foo.rs 强>
extern crate kodecheck_spellcheck;
fn main() {
kodecheck_spellcheck::spellcheck::corrections::create_candidates();
}
编译它有错误:
error: module `spellcheck` is private
--> examples/foo.rs:4:5
|
4 | kodecheck_spellcheck::spellcheck::corrections::create_candidates();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
我们还可以创建MCVE:
mod spellcheck {
mod edits {
static ALPHABET: &'static str = "";
pub fn edits1() {
println!("{}", ALPHABET);
}
}
pub mod corrections {
pub fn create_candidates() {
::spellcheck::edits::edits1();
}
}
}
fn main() {}
请注意,这与您的示例不同,因为main
为空。您的图书馆包没有调用任何内容的main
方法。您还可以明确指出它是一个库包,但这不太为人所知:
#![crate_type="lib"]
mod spellcheck {
mod edits {
static ALPHABET: &'static str = "";
pub fn edits1() {
println!("{}", ALPHABET);
}
}
pub mod corrections {
pub fn create_candidates() {
::spellcheck::edits::edits1();
}
}
}
因为所有代码都是私有模块,所以
要解决此问题,我建议将 src / spellcheck / mod.rs 合并到 src / lib-spellcheck.rs 中。您也可以将模块公开,但我认为没有理由拥有额外的模块。
我也认为没有理由将 src / lib.rs 重命名为 src / lib-spellcheck.rs ;只要离开 lib.rs ,它就更具惯用性。
此外,您应该继续使用Rust风格。大括号与签名在同一行:
fn calc_p(word: &str, dict: &Dictionary) -> f32 {
// ...
像rustfmt这样的工具可以帮助您应用正确的风格。