是否相当于生 rust 中的__func__或__FUNCTION__?

tzcvj98z  于 2022-11-24  发布在  其他
关注(0)|答案(5)|浏览(143)

在C和C中,您可以使用C99和C11通过__func__宏获取当前正在执行的函数的名称,对于MSVC,可以使用___FUNCTION___
在《 rust 》中有没有类似的东西?
C语言中__func__的示例:

#include "stdio.h"

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

int main() {
    funny_hello();
}

输出Hello from funny_hello

voase2hg

voase2hg1#

你可以和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]
    }}
}

请注意,这给出了完整的路径名,因此是my::path::my_func而不是my_funcA demo is available.

83qze16e

83qze16e2#

有一个关于这一点的RFC,但它从来没有达成一致或实施。
不存在的理由:
一般来说,我认为我们中得任何人都没有过多地考虑过这些“与调试相关”得宏得长期稳定性.它们中得大多数看起来都是无害得,但是承诺为所有Rust程序永远提供所有这些宏是一个强有力得承诺.我们可能需要简要地考虑一下这些宏得故事,同时考虑添加这个新宏.
也许Rust将来会有类似的东西,
但是现在您需要依靠自己的标记。

  • 补充说明:* __FUNCTION__是非标准的,__func__存在于C99 / C++11中。
jei2mxaa

jei2mxaa3#

添加到Veedrac's answer,您可以通过添加以下内容来获得不带完整路径的函数名:

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],
        }
    }};
}

例如,您将得到my_func而不是my::path::my_func

tp5buhyn

tp5buhyn4#

看起来function_name板条箱可以做到这一点。
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",
    );
}

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

t1qtbnec

t1qtbnec5#

虽然缺乏官方支持,但有stdext crate(RFC问题中也提到了)使其易于使用。

use stdext::function_name;

fn foo() {
  println!("{}", function_name!());
}

这包括模块/特征名称,如::module::Trait::function(如果有)。
如果你只关心名字而不是它的整个路径,你可以对trait方法做一些类似的事情(记住,这会有运行时开销,你可能想用OnceCell来限制它):

let fn_name = function_name!()
              .rsplit_once(':')
              .expect("could not parse function name")
              .1;

相关问题