函数条目类型
引用函数条目或类似元组结构或枚举变量的构造函数时,会生成其 函数条目类型 的大小为零的值。 该类型明确标识函数 - 其名称、类型参数和其提前绑定的生命周期参数 (但不包括其延迟绑定的生命周期参数,这些参数仅在调用函数时分配) - 因此该值不需要包含实际的函数指针,并且调用函数时不需要进行间接寻址。
没有直接引用函数条目类型的语法,但编译器在错误消息中将显示类型为类似于 fn(u32) -> i32 {fn_name}
的类型。
因为函数条目类型明确标识函数,不同函数的条目类型 - 不同的条目,或者相同条目的不同泛型 - 是不同的,混合它们会产生类型错误:
#![allow(unused)] fn main() { fn foo<T>() { } let x = &mut foo::<i32>; *x = foo::<u32>; //~ ERROR 类型不匹配 }
然而,从具有相同签名的函数条目到 函数指针 存在 强制转换 ,当期望直接使用函数指针时,会被触发。
当在同一 if
或 match
的不同分支中遇到具有相同签名的不同函数条目类型时,也会触发这种转换:
#![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
, Send
和 Sync
。