简体   繁体   中英

How can I obtain the address of a closure in Rust?

let say_hello = || println!("hello");

How can I display the address of the closure?

You can use a raw pointer conversion:

fn main() {
    let say_hello = || println!("hello");
    let address = (&say_hello as *const _) as usize;
    println!("{address}");
}

Playground

Also using std::ptr::addr_of and casting again:

let same_address = std::ptr::addr_of!(say_hello) as usize;

Playground

The answer to this question really depends on whether you mean the closure object itself, or the closure's call function.

For example, in this case, the closure captures a variable:

let mut foo = 0;

let mut bar = || foo += 1;

And hence, bar must carry within it a &mut foo .

Therefore, the address of the actual code which is run is different from the address of the closure object.

To concrete this distinction, examine this example:

fn foo() {}

let bar = foo; // `bar` itself is the address of the code for foo.
println!("{:?}", bar as usize); // Prints the address of the code of foo.
println!("{:?}", &bar as *const _ as usize); // Prints the address of `bar`

The second line is essentially what @Netwave's answer does above.

If you are instead looking for the first case, then this isnt necessarily always possible.

If your closure captures items, then it can't be converted to an address of the code in stable rust, since this'd require you have access to it's implementation of FnOnce / Fn / FnMut . However, if you're ok with unstable rust, here's how you'd do it:

#![feature(unboxed_closures, fn_traits)]

fn main() {
    let mut x = 0;
    let mut foo = || x += 1;
    
    print_addr(foo);
}

fn print_addr<F: FnMut()>(_: F) {
    println!("{:?}", <F as std::ops::FnMut<()>>::call_mut as usize);
}

If your closure doesn't capture anything, then the correct way to get the address is to cast it to a function pointer and then cast that to a number:

fn main() {
    let foo = || println!("Abc");
    
    println!("{:?}", foo as fn() as usize);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM