如何在函数调用时显示编译器警告?

wiz*_*zz4 3 static-analysis compiler-warnings rust

我有一个我想在我的模块中导出的函数,以便人们可以使用它。然而,在 95% 的情况下,使用它是一个坏主意。

/// Check whether foo is a metasyntactic variable.
/// 
/// **Using this function is a mistake.** This function is slow,
/// since checking widgets is an extremely expensive operation.
/// You should be keeping track of what's what, and ideally will
/// never need to use this function.
/// 
/// If you _do_ need to use this function, please consider a refactor.
pub fn test_widget(foo: String) -> bool {
    false
}
Run Code Online (Sandbox Code Playgroud)

它主要用于文档和测试目的。但是,因为有 5% 的情况下这样的东西可能真正有用,所以我想保留它。

希望人们不小心使用它,所以我想调用该函数会导致编译器警告(除非他们明确地用allow或其他东西覆盖它)。我怎样才能做到这一点?

Jus*_*tin 7

您可以将该函数标记为已弃用

// Consider summarizing this and linking to the docs, rather than putting the
// entire message here.
#[deprecated(note=
    "**Using this function is a mistake.**
This function is slow,
since checking widgets is an extremely expensive operation.
You should be keeping track of what's what, and ideally will
never need to use this function.

If you _do_ need to use this function, please consider a refactor.")]
pub fn test_widget(foo: String) -> bool {
    /// Check whether foo is a metasyntactic variable.
    false
}
Run Code Online (Sandbox Code Playgroud)

如果用户使用该功能,他们会收到警告:

warning: use of deprecated item 'test_widget': **Using this function is a mistake.**
This function is slow,
since checking widgets is an extremely expensive operation.
You should be keeping track of what's what, and ideally will
never need to use this function.

If you _do_ need to use this function, please consider a refactor.
Run Code Online (Sandbox Code Playgroud)

但他们可以通过以下方式将其关闭#[allow(deprecated)]

#[allow(deprecated)]
test_widget("Hello, World!".to_string()); // no warning
Run Code Online (Sandbox Code Playgroud)

游乐场链接。

  • @Shepmaster [我可以滥用另一个属性吗](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=ec44574f19d6039421c7460c1c4add40)?:D (3认同)
  • 这个答案有效,但我不太喜欢它,因为它在语义上滥用了“已弃用”属性。然而,这可能是当前唯一可用的方法。 (2认同)

mca*_*ton 5

must_use似乎很贴切,并允许指定自定义消息:

#[must_use = "Calling this function is a bad idea"]
pub struct BadIdeaFunction(bool);

impl BadIdeaFunction {
    pub fn i_acknowledge_calling_this_function_is_a_bad_idea(self) -> bool {
        self.0
    }
}

/// Check whether foo is a metasyntactic variable.
///
/// **Using this function is a mistake.** This function is slow,
/// since checking widgets is an extremely expensive operation.
/// You should be keeping track of what's what, and ideally will
/// never need to use this function.
///
/// If you _do_ need to use this function, please consider a refactor.
pub fn test_widget() -> BadIdeaFunction {
    BadIdeaFunction(false)
}

fn main() {
    test_widget(); // gives a warning, but the next one doesn't

    test_widget().i_acknowledge_calling_this_function_is_a_bad_idea();
}
Run Code Online (Sandbox Code Playgroud)

这将创建一个带有自定义消息的警告:

warning: unused `BadIdeaFunction` that must be used
  --> src/main.rs:23:5
   |
23 |     test_widget();
   |     ^^^^^^^^^^^^^^
   |
   = note: #[warn(unused_must_use)] on by default
   = note: Calling this function is a bad idea
Run Code Online (Sandbox Code Playgroud)

  • @trentcl 你是对的!自动补全让这个问题很容易被绕过![我们需要使用大写来使其成为正确的实际挑战!](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=bb66ecd1fe3142a9e23404bd5f0015d4) (2认同)