在Rust中等效__func__或__FUNCTION__?

Pur*_*reW 15 macros rust

在C和C++中,您可以通过__func__C99和C++ 11以及___FUNCTION___MSVC 的宏获取当前正在执行的函数的名称.

在Rust中有相同的吗?

__func__C中的示例:

#include "stdio.h"

void funny_hello() {
    printf ("Hello from %s\n", __func__);
}

int main() {
    funny_hello();
}
Run Code Online (Sandbox Code Playgroud)

输出Hello from funny_hello.

Tre*_*key 13

有一个关于此的RFC,但它从未达成一致或实施.

缺席的理由:

"总的来说,我不认为我们中的任何一个人在长期稳定性方面对这些"调试相关"的宏给出了过多的考虑.大多数它们看起来相当无害,但承诺为所有Rust程序提供所有这些.永远是我们的坚定承诺.我们可能希望在考虑添加这个新宏的同时,简要地考虑这些宏的故事."

也许Rust将来会有类似的东西,
但是现在你需要依靠自己的标签.

附注: __FUNCTION__是非标准的,__func__存在于C99/C++ 11中.


Tro*_*els 10

看来function_namecrate 可以做到这一点。

https://docs.rs/function_name/latest/function_name/

文档中的示例是

use ::function_name::named;

#[named]
fn my_super_duper_function ()
{
    assert_eq!(
        function_name!(),
        "my_super_duper_function",
    );
}
Run Code Online (Sandbox Code Playgroud)

我没有参与该项目,也没有实际尝试过。


Vee*_*rac 6

您可以与一起破解std::any::type_name

macro_rules! function {
    () => {{
        fn f() {}
        fn type_name_of<T>(_: T) -> &'static str {
            std::any::type_name::<T>()
        }
        let name = type_name_of(f);
        &name[..name.len() - 3]
    }}
}
Run Code Online (Sandbox Code Playgroud)

请注意,这给出了完整的路径名,所以my::path::my_func不只是my_func演示可用。

  • @TeohHanHui 这也会隐藏正常的闭包,而不仅仅是隐式的异步闭包。 (2认同)

Ale*_*xis 5

添加到Veedrac 的答案中,您可以通过添加以下内容来获取没有完整路径的函数名称:

macro_rules! function {
    () => {{
        fn f() {}
        fn type_name_of<T>(_: T) -> &'static str {
            std::any::type_name::<T>()
        }
        let name = type_name_of(f);

        // Find and cut the rest of the path
        match &name[..name.len() - 3].rfind(':') {
            Some(pos) => &name[pos + 1..name.len() - 3],
            None => &name[..name.len() - 3],
        }
    }};
}
Run Code Online (Sandbox Code Playgroud)

你会得到my_func而不是my::path::my_func例如。