如何定义一个全局闭包/函子并传递给一个函数来确定它是否是 Rust 中预定义的?

问题描述 投票:0回答:1

我想预定义几个函数/关闭。它们可用于传递给一个函数,该函数确定它是否是预定义的。

// static? const? or global fn()?
static prefined1: Fn()+'static = || { do_some_thing(); }
static prefined2: Fn()+'static = || { do_other_thing();}

fn call_func(f: impl Fn()+'static) {
    if f == predefined1 {  // how to compare closures???
         // do some thing with predefined1 
    } else if f == predefined2 {
         // do some thing with predefined12
    } else {
         // others.
    }
}
rust static closures
1个回答
0
投票

函数不能直接比较,但可以比较它们的指针:

static PREDEFINED_1: fn() = || { println!("foo"); };
static PREDEFINED_2: fn() = || { println!("bar"); };

fn call_func(f: &dyn Fn()) {
    if std::ptr::eq(f, &PREDEFINED_1) {
         println!("found 1");
    } else if std::ptr::eq(f, &PREDEFINED_2)  {
         println!("found 2");
    } else {
         println!("found neither");
    }
}

pub fn main() {
    call_func(&PREDEFINED_1);
    call_func(&PREDEFINED_2);
    call_func(&|| { println!("foo") });
}

一般来说,这是一个大错误,因为编译器可能会将相同的函数折叠到同一地址或发出 vtable 的多个副本(例如由于 inlinedcodegen 单元)。

出于这些原因,您可能应该使用

enum
来代替:

enum Func {
    Predefined1,
    Predefined2,
    Custom(Box<dyn Fn()>)
}

fn call_func(f: Func) {
    match f {
        Func::Predefined1 => println!("found 1"),
        Func::Predefined2 => println!("found 2"),
        Func::Custom(_c) => println!("found neither"),
    }
}

pub fn main() {
    call_func(Func::Predefined1);
    call_func(Func::Predefined2);
    call_func(Func::Custom(Box::new(|| { println!("foo"); })));
}
© www.soinside.com 2019 - 2024. All rights reserved.