![](/img/trans.png)
[英]What's the difference between extern fn and extern “C” fn in Rust?
[英]What's the practical difference between fn item and fn pointer?
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!("{}", func_of_func(is_positive, 8));
}
这不编译:
error[E0308]: mismatched types
--> src/main.rs:9:33
|
9 | println!("{}", func_of_func(is_positive, 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!("{}", func_of_func(&is_positive, 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));
println!("{}", func_of_func(is_positive, 8));
}
使用Fn
trait 更为常见,它的好处是允许闭包和函数
fn func(x: i64) -> bool {
true
}
fn func_of_func(callback: impl FnOnce(i64) -> bool, arg: i64) -> bool {
callback(arg)
}
fn main() {
let is_positive = func;
println!("{}", func_of_func(is_positive, 8));
println!("{}", func_of_func(is_positive, 8));
}
fn(i64) -> bool
已经是一个函数指针,所以&fn(i64) -> bool
是一个函数指针的引用。 由于函数指针是Copy
,你永远不应该有任何理由写这个。
如果您正在编写一个将类似函数的东西作为参数的函数,您通常应该使用泛型(或impl Fn
,如Mike Graham 的回答,这意味着同样的事情):
fn func_of_func<F: FnOnce(i64) -> bool>(callback: F, arg: i64) -> bool {
callback(arg)
}
这意味着当您使用func
等函数项调用func_of_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
类型参数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.