fn项和fn指针之间的实际区别是什么? [英] What's the practical difference between fn item and fn pointer?

查看:189
本文介绍了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!("{}", 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的指针之间的实际区别.

Why does this error occur while I have passed a pointer, not fn? I want to know the practical difference between using fn and pointer to fn.

推荐答案

fn(i64) -> bool已经有函数指针,因此&fn(i64) -> bool是引用指向函数指针.由于函数指针是Copy,因此您永远没有任何理由要编写此指针.

fn(i64) -> bool is already a function pointer, so &fn(i64) -> bool is a reference to a function pointer. Since function pointers are Copy, you should never have any reason to write this.

如果您要编写一个函数,将类似函数的参数用作参数,则通常应使用泛型(或impl Fn,如

If you're writing a function that takes something function-like as an argument, you should usually use generics (or impl Fn, as in Mike Graham's answer, which means the same thing):

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

这意味着,当使用诸如func之类的函数项调用func_of_func时,callback将被编译为直接函数调用而不是函数指针,这对于编译器来说更容易优化.

This means that when you call func_of_func with a function item such as func, callback will be compiled to a direct function call instead of a function pointer, which is easier for the compiler to optimize.

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

If the function cannot be made generic (perhaps because it's a member of an object safe trait), you should usually use trait objects instead, which allows the caller to pass a closure:

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的类型参数最有用.

Function pointers should only be used when the function definitely cannot capture anything. They are mostly useful for FFI with C, and as type parameters to PhantomData in generic structs.

这篇关于fn项和fn指针之间的实际区别是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆