在Rust中等效__func__或__FUNCTION__?

时间:2016-06-28 23:48:59

标签: macros rust

在C和C ++中,您可以通过__func__宏获取当前正在执行的函数的名称,其中包含C99& MSVC的C ++ 11和___FUNCTION___

Rust中有相同的内容吗?

C中的__func__示例:

#include "stdio.h"

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

int main() {
    funny_hello();
}

输出Hello from funny_hello

3 个答案:

答案 0 :(得分:12)

关于此问题有一个RFC,但它从未达成一致或已实施。

缺席的理由:

  

“总的来说,我认为我们中的任何一个人都没有过多   从长远来看,这些“调试相关”的宏   稳定性。他们中的大多数似乎相当无害,但承诺   为所有Rust程序提供所有这些永远是强大的   承诺。我们可能想简要地考虑一下这些故事   宏与结合考虑添加这个新的宏。“

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

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

答案 1 :(得分:4)

如果您只在不稳定时使用它,可以与type_name

一起攻击一个
#![feature(core_intrinsics)]

macro_rules! function {
    () => {{
        fn f() {}
        fn type_name_of<T>(_: T) -> &'static str {
            extern crate core;
            unsafe { core::intrinsics::type_name::<T>() }
        }
        let name = type_name_of(f);
        &name[6..name.len() - 4]
    }}
}

当然,您可以使用cfg回归稳定的无聊默认

#![cfg_attr(feature = "type_name", feature(core_intrinsics))]

#[cfg(feature = "type_name")]
macro_rules! function {
    ... // as before
}

#[cfg(not(feature = "type_name"))]
macro_rules! function {
    () => {{ "<fn>" }}
}

请注意,这会提供完整的路径名,因此my::path::my_func而非my_funcA demo is available.

答案 2 :(得分:1)

添加到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