Primitive Type fn

1.0.0 ·
Expand description

函数指针,例如 fn(usize) -> bool

另请参见 traits FnFnMutFnOnce

函数指针是指向 code 的指针,而不是数据。它们可以像函数一样被调用。 像引用一样,函数指针被假定为不为空,所以如果您想通过 FFI 传递函数指针并能够容纳空指针,请使用所需的签名来创建类型 Option<fn()>

Safety

普通函数指针是通过强制转换不能捕获环境的普通函数或闭包而获得的:

fn add_one(x: usize) -> usize {
    x + 1
}

let ptr: fn(usize) -> usize = add_one;
assert_eq!(ptr(5), 6);

let clos: fn(usize) -> usize = |x| x + 5;
assert_eq!(clos(5), 10);
Run

除了根据其签名而有所不同外,函数指针还具有两种形式:安全和不安全。 普通 fn() 函数指针只能指向安全函数,而 unsafe fn() 函数指针可以指向安全或不安全函数。

fn add_one(x: usize) -> usize {
    x + 1
}

unsafe fn add_one_unsafely(x: usize) -> usize {
    x + 1
}

let safe_ptr: fn(usize) -> usize = add_one;

// ERROR: 不匹配的类型:预期正常 fn,发现不安全 fn let bad_ptr: fn(usize) -> usize=add_one_unsafely;

let unsafe_ptr: unsafe fn(usize) -> usize = add_one_unsafely;
let really_safe_ptr: unsafe fn(usize) -> usize = add_one;
Run

ABI

最重要的是,函数指针可以根据它们使用的 ABI 有所不同。这是通过在类型之前添加 extern 关键字,然后是所涉及的 ABI 来实现的。默认的 ABI 是 “Rust”,即 fn() 是与 extern "Rust" fn() 完全相同的类型。 指向带有 C ABI 的函数的指针的类型为 extern "C" fn()

extern "ABI" { ... } 块用 ABI “ABI” 声明函数。此处的默认值为 “C”,即,在 extern {...} 块中声明的函数具有 “C” ABI。

有关更多信息和受支持的 ABI 列表,请参见 nomicon 中关于外部调用约定的部分

可变函数

“C” 或 “cdecl” ABI 的 Extern 函数声明也可以 variadic,允许使用可变数量的参数来调用它们。普通的 Rust 函数,即使是 extern "ABI" 的函数,也不能可变。 有关更多信息,请参见 关于可变参数函数的 nomicon 部分

创建函数指针

如果 bar 是函数的名称,则表达式 bar不是 函数指针。相反,它表示唯一标识函数 bar 的无法命名类型的值。该值的大小为零,因为该类型已经标识了该函数。 这样做的好处是 “calling” 值 (实现 Fn* traits) 不需要动态分配。

零大小的类型 强制 到常规函数指针。例如:

use std::mem;

fn bar(x: i32) {}

let not_bar_ptr = bar; // `not_bar_ptr` 是零大小的,唯一标识是 `bar`
assert_eq!(mem::size_of_val(&not_bar_ptr), 0);

let bar_ptr: fn(i32) = not_bar_ptr; // 强制转换为函数指针
assert_eq!(mem::size_of_val(&bar_ptr), mem::size_of::<usize>());

let footgun = &bar; // 这是对标识 `bar` 的零大小类型的共享引用
Run

最后一行显示 &bar 也不是函数指针。相反,它是特定于函数的 ZST 的引用。当 bar 是一个函数时,&bar 基本上不是您想要的。

转换为整数和从整数转换

您将函数指针直接转换为整数:

let fnptr: fn(i32) -> i32 = |x| x+2;
let fnptr_addr = fnptr as usize;
Run

但是,直接回退是不可能的。您需要使用 transmute:

let fnptr = fnptr_addr as *const ();
let fnptr: fn(i32) -> i32 = unsafe { std::mem::transmute(fnptr) };
assert_eq!(fnptr(40), 42);
Run

至关重要的是,我们在转换为函数指针之前 as-cast 为一个裸指针。 这避免了整数到指针 transmute,这可能是有问题的。 在裸指针 (即两个指针类型) 之间转换是可以的。

请注意,所有这些都不能移植到函数指针和数据指针具有不同大小的平台。

trait 实现

在本文档中,简写 fn (T₁, T₂,…, Tₙ) 用于表示可变长度的非可变函数指针。请注意,这是一种方便的符号,以避免重复文档,不是有效的 Rust 语法。

由于 Rust 的类型系统中的临时限制,这些 traits 仅在 "Rust""C" ABI 上使用不超过 12 个参数的函数上实现。在未来,这可能会改变:

以下 traits 是为具有任意数量参数和任意 ABI 的函数指针实现的。 这些 traits 具有由编译器自动生成的实现,因此不受缺少语言特性的限制:

此外,所有 safe 函数指针都实现了 FnFnMutFnOnce,因为这些 traits 是编译器特别知道的。

Trait Implementations§

source§

impl<Ret, T> Clone for fn (T₁, T₂, …, Tₙ) -> Ret

这个 trait 是在具有任意数量参数的函数指针上实现的。

source§

fn clone(&self) -> Self

返回值的副本。 Read more
source§

fn clone_from(&mut self, source: &Self)

source 执行复制分配。 Read more
source§

impl<Ret, T> Copy for fn (T₁, T₂, …, Tₙ) -> Ret

这个 trait 是在具有任意数量参数的函数指针上实现的。

Auto Trait Implementations§

§

impl<Ret, T> RefUnwindSafe for fn (T₁, T₂, …, Tₙ) -> Ret

§

impl<Ret, T> Send for fn (T₁, T₂, …, Tₙ) -> Ret

§

impl<Ret, T> Sync for fn (T₁, T₂, …, Tₙ) -> Ret

§

impl<Ret, T> Unpin for fn (T₁, T₂, …, Tₙ) -> Ret

§

impl<Ret, T> UnwindSafe for fn (T₁, T₂, …, Tₙ) -> Ret

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

获取 selfTypeIdRead more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

从拥有的值中一成不变地借用。 Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

从拥有的值中借用。 Read more
source§

impl<F> Debug for Fwhere F: FnPtr,

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

使用给定的格式化程序格式化该值。 Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

返回未更改的参数。

source§

impl<F> Hash for Fwhere F: FnPtr,

source§

fn hash<HH>(&self, state: &mut HH)where HH: Hasher,

将该值输入给定的 HasherRead more
1.3.0 · source§

fn hash_slice<H: Hasher>(data: &[Self], state: &mut H)where Self: Sized,

将这种类型的切片送入给定的 Hasher 中。 Read more
source§

impl<T, U> Into<U> for Twhere U: From<T>,

source§

fn into(self) -> U

调用 U::from(self)

也就是说,这种转换是 From<T> for U 实现选择执行的任何操作。

source§

impl<F> Ord for Fwhere F: FnPtr,

source§

fn cmp(&self, other: &F) -> Ordering

此方法返回 selfother 之间的 OrderingRead more
1.21.0 · source§

fn max(self, other: Self) -> Selfwhere Self: Sized,

比较并返回两个值中的最大值。 Read more
1.21.0 · source§

fn min(self, other: Self) -> Selfwhere Self: Sized,

比较并返回两个值中的最小值。 Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Selfwhere Self: Sized + PartialOrd,

将值限制在某个时间间隔内。 Read more
source§

impl<F> PartialEq<F> for Fwhere F: FnPtr,

source§

fn eq(&self, other: &F) -> bool

此方法测试 selfother 值是否相等,并由 == 使用。
source§

fn ne(&self, other: &Rhs) -> bool

此方法测试 !=。 默认实现几乎总是足够的,并且不应在没有充分理由的情况下被覆盖。
source§

impl<F> PartialOrd<F> for Fwhere F: FnPtr,

source§

fn partial_cmp(&self, other: &F) -> Option<Ordering>

如果存在,则此方法返回 selfother 值之间的顺序。 Read more
source§

fn lt(&self, other: &Rhs) -> bool

此方法测试的内容少于 (对于 selfother),并且由 < 操作员使用。 Read more
source§

fn le(&self, other: &Rhs) -> bool

此方法测试小于或等于 (对于 selfother),并且由 <= 运算符使用。 Read more
source§

fn gt(&self, other: &Rhs) -> bool

此方法测试大于 (对于 selfother),并且由 > 操作员使用。 Read more
source§

fn ge(&self, other: &Rhs) -> bool

此方法测试是否大于或等于 (对于 selfother),并且由 >= 运算符使用。 Read more
source§

impl<'a, F> Pattern<'a> for Fwhere F: FnMut(char) -> bool,

§

type Searcher = CharPredicateSearcher<'a, F>

🔬This is a nightly-only experimental API. (pattern #27721)
此模式的关联搜索者
source§

fn into_searcher(self, haystack: &'a str) -> CharPredicateSearcher<'a, F>

🔬This is a nightly-only experimental API. (pattern #27721)
selfhaystack 构造关联的搜索器以进行搜索。
source§

fn is_contained_in(self, haystack: &'a str) -> bool

🔬This is a nightly-only experimental API. (pattern #27721)
检查模式是否与 haystack 中的任何位置匹配
source§

fn is_prefix_of(self, haystack: &'a str) -> bool

🔬This is a nightly-only experimental API. (pattern #27721)
检查模式是否在 haystack 的前面匹配
source§

fn strip_prefix_of(self, haystack: &'a str) -> Option<&'a str>

🔬This is a nightly-only experimental API. (pattern #27721)
如果匹配,则从 haystack 的正面删除模式。
source§

fn is_suffix_of(self, haystack: &'a str) -> boolwhere CharPredicateSearcher<'a, F>: ReverseSearcher<'a>,

🔬This is a nightly-only experimental API. (pattern #27721)
检查模式是否与 haystack 的后面匹配
source§

fn strip_suffix_of(self, haystack: &'a str) -> Option<&'a str>where CharPredicateSearcher<'a, F>: ReverseSearcher<'a>,

🔬This is a nightly-only experimental API. (pattern #27721)
如果匹配,则从 haystack 的后面删除模式。
source§

impl<F> Pointer for Fwhere F: FnPtr,

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

使用给定的格式化程序格式化该值。
source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

发生转换错误时返回的类型。
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

执行转换。
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

发生转换错误时返回的类型。
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

执行转换。
source§

impl<F> Eq for Fwhere F: FnPtr,