函数条目类型

引用函数条目或类似元组结构或枚举变量的构造函数时,会生成其 函数条目类型 的大小为零的值。 该类型明确标识函数 - 其名称、类型参数和其提前绑定的生命周期参数 (但不包括其延迟绑定的生命周期参数,这些参数仅在调用函数时分配) - 因此该值不需要包含实际的函数指针,并且调用函数时不需要进行间接寻址。

没有直接引用函数条目类型的语法,但编译器在错误消息中将显示类型为类似于 fn(u32) -> i32 {fn_name} 的类型。

因为函数条目类型明确标识函数,不同函数的条目类型 - 不同的条目,或者相同条目的不同泛型 - 是不同的,混合它们会产生类型错误:

#![allow(unused)]
fn main() {
fn foo<T>() { }
let x = &mut foo::<i32>;
*x = foo::<u32>; //~ ERROR 类型不匹配
}

然而,从具有相同签名的函数条目到 函数指针 存在 强制转换 ,当期望直接使用函数指针时,会被触发。 当在同一 ifmatch 的不同分支中遇到具有相同签名的不同函数条目类型时,也会触发这种转换:

#![allow(unused)]
fn main() {
let want_i32 = false;
fn foo<T>() { }

// 在这里,`foo_ptr_1` 具有函数指针类型 `fn()`
let foo_ptr_1: fn() = foo::<i32>;

// ... `foo_ptr_2` 也具有相同的函数指针类型 - 这样类型检查通过了
let foo_ptr_2 = if want_i32 {
    foo::<i32>
} else {
    foo::<u32>
};
}

所有的函数条目都实现了 Fn , FnMut , FnOnce , Copy , Clone , SendSync