微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

fn项和fn指针之间的实际区别是什么? 参考文献

如何解决fn项和fn指针之间的实际区别是什么? 参考文献

fn func(_: i64) -> bool {
    true
}

fn func_of_func(callback: &fn(i64) -> bool,arg: i64) -> bool {
    (*callback)(arg)
}

fn main() {
    let is_positive = &func;
    println!("{}",func_of_func(is_positive,8));
    println!("{}",8));
}

无法编译:

error[E0308]: mismatched types
 --> src/main.rs:9:33
  |
9 |     println!("{}",8));
  |                                 ^^^^^^^^^^^ expected fn pointer,found fn item
  |
  = note: expected reference `&fn(i64) -> bool`
             found reference `&fn(i64) -> bool {func}`

为什么我传递了指针而不是fn时会发生此错误?我想知道使用fn和指向fn的指针之间的实际区别。

解决方法

您应该可以通过以下方式解决此问题

fn func_of_func(callback: &fn(i64) -> bool,arg: i64) -> bool {
    (*callback)(arg)
}

fn main() {
    let is_positive = func;
    println!("{}",func_of_func(&is_positive,8));
    println!("{}",8));
}

或更直接地通过不添加间接级别

fn func_of_func(callback: fn(i64) -> bool,arg: i64) -> bool {
    callback(arg)
}

fn main() {
    let is_positive = func;
    println!("{}",func_of_func(is_positive,8));
}

使用Fn特征更常见,它具有允许闭包和函数的优点

fn func(x: i64) -> bool {
    true
}
    
fn func_of_func(callback: impl FnOnce(i64) -> bool,8));
}
,

fn(i64) -> boolalready a function pointer,因此&fn(i64) -> bool是对函数指针的引用。由于函数指针是Copy,因此您永远都没有理由编写它。

如果您要编写一个函数,该函数将类似函数的参数用作参数,则通常应使用泛型(或impl Fn,如Mike Graham's answer中一样,表示同一意思):>

fn func_of_func<F: FnOnce(i64) -> bool>(callback: F,arg: i64) -> bool {
    callback(arg)
}

这意味着,当您使用func_of_func之类的函数项调用func时,callback将被编译为直接函数调用,而不是函数指针,这对于编译器进行优化。

如果函数不能被通用化(也许是因为它是对象安全特征的成员),则通常应使用特征对象,从而允许调用者传递闭包:

fn func_of_func(callback: &dyn Fn(i64) -> bool,arg: i64) -> bool { ... }
fn func_of_func(callback: &mut dyn FnMut(i64) -> bool,arg: i64) -> bool { ... }
// using `FnOnce` requires boxing
fn func_of_func(callback: Box<dyn FnOnce(i64) -> bool>,arg: i64) -> bool { ... }

仅当函数绝对不能捕获任何内容时才应使用函数指针。它们对于使用C的FFI以及在通用结构中作为PhantomData的类型参数最有用。

参考文献

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。