函数项类型
当被引用时,函数项,或者类元组结构体或枚举变体的构造函数,会产生一个零大小的其函数项类型的值。
该类型明确标识了函数 - 它的名称、它的类型参数以及它的早绑定生命周期参数(但不包括它的晚绑定生命周期参数,这些参数只在函数被调用时才被指定) - 因此该值不需要包含实际的函数指针,并且在调用函数时不需要间接引用。
没有直接引用函数项类型的语法,但编译器会在错误消息中将其类型显示为类似 fn(u32) -> i32 {fn_name} 的形式。
由于函数项类型明确标识了函数,不同函数(不同的项,或带有不同泛型参数的同一项)的项类型是不同的,混合使用它们会导致类型错误。
#![allow(unused)] fn main() { fn foo<T>() { } let x = &mut foo::<i32>; *x = foo::<u32>; //~ ERROR mismatched types }
然而,存在从函数项到具有相同签名的函数指针的强制转换,这种强制转换不仅在使用函数指针直接期望的场景下触发,而且当具有相同签名的不同函数项类型在同一个 if 或 match 的不同分支中出现时也会触发。
#![allow(unused)] fn main() { let want_i32 = false; fn foo<T>() { } // `foo_ptr_1` has function pointer type `fn()` here let foo_ptr_1: fn() = foo::<i32>; // ... and so does `foo_ptr_2` - this type-checks. let foo_ptr_2 = if want_i32 { foo::<i32> } else { foo::<u32> }; }