如何在Rust中找到函数调用者的类型?

时间:2018-07-27 07:36:50

标签: function reflection rust

如何在函数中获取呼叫者类型?

struct A;
struct B;

impl A {
    fn new() -> Self {
        A
    }
    fn call_function(&self) {
        B::my_function();
    }
}

impl B {
    pub fn my_function() {
        println!("Hello");
        // println!("{}" type_of_the_caller) // I want to get type A here
        // Is it possible to get the caller type which is A in this case?
    }
}

fn main() {
    let a = A::new();
    a.call_function();
}

Here是操场上的工作代码。这是示例的简化代码。

2 个答案:

答案 0 :(得分:4)

Rust没有像这样的内置设备。如果您想知道函数内部的某些上下文,则需要将其作为参数传递。

此外,Rust无法获得类型名称,因此您也必须提供该名称。例如,具有特征:

trait Named {
    fn name() -> &'static str;
}

impl Named for A {
    fn name() -> &'static str {
        "A"
    }
}

您可能会这样使用:

impl B {
    pub fn my_function<T: Named>(_: &T) {
        println!("Hello");
        println!("{}", T::name());
    }
}

呼叫时只需传递呼叫者:

impl A {
    fn call_function(&self) {
        B::my_function(self);
    }
}

输出:

Hello
A

答案 1 :(得分:0)

您可以让编译器通过创建宏并利用stringify!宏来编写样板。

struct A;
struct B;
struct C;

trait Named {
    fn name() -> &'static str;
}

macro_rules! make_named {
    ( $($x:ty),* ) => {
        $(
        impl Named for $x {
            fn name() -> &'static str {
                stringify!($x)
            }
        }
        )*
    };
}

make_named!(A, B);
make_named!(C);

fn main() {
    println!("{:#?}", A::name());
    println!("{:#?}", B::name());
    println!("{:#?}", C::name());
}

playground