简体   繁体   English

如何获取Rust中的闭包地址?

[英]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:还使用std::ptr::addr_of并再次投射:

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.这个问题的答案实际上取决于您是指闭包 object 本身,还是闭包的调用 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 .因此, bar必须在其中携带一个&mut foo

Therefore, the address of the actual code which is run is different from the address of the closure object.因此,实际运行的代码地址与闭包地址 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.第二行基本上就是@Netwave 上面的回答。

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 .如果您的闭包捕获项目,则无法将其转换为稳定 rust 中代码的地址,因为这需要您有权访问它的FnOnce / Fn / FnMut However, if you're ok with unstable rust, here's how you'd do it:但是,如果您对不稳定的 rust 没问题,那么您可以这样做:

#![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:如果您的闭包没有捕获任何内容,那么获取地址的正确方法是将其转换为 function 指针,然后将其转换为数字:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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