为何Rust中cmp::Eq为fn(&'a T)->T实现却未为fn(&T)->T实现?
为什么带生命周期的函数指针实现了
Eq,而不带的没有? 这个差异确实是Rust有意设计的结果,核心原因和函数指针的类型本质、生命周期的处理逻辑直接相关,咱们拆开来理清楚:
两种函数指针的本质区别
- 带显式生命周期的
fn(&'a T) -> T:这是一个已经单态化的具体类型。每个不同的生命周期参数'a,都会对应一个独立的函数指针类型。这类类型的大小固定,指向的是编译期就确定的函数内存地址,所以Rust可以安全地为它实现Eq(以及PartialEq、Hash等 trait)——毕竟两个相同类型的函数指针,只要指向同一个函数,就肯定相等。 - 不带显式生命周期的
fn(&T) -> T:这其实是一个高阶生命周期的抽象类型,等价于for<'b> fn(&'b u32) -> u32,意思是“能接受任意生命周期的&T参数、返回T的所有函数”。它不是一个具体的、单态化后的类型,编译期无法确定它对应的具体内存地址,自然没办法实现Eq——你没法拿一个“泛指所有符合条件的函数”的抽象类型,去做相等比较。
对应到你的代码例子
第一个代码片段里,type Eq = fn(&'a u32) -> u32的生命周期'a和Bar<'a>绑定,是一个具体的、确定的生命周期参数,所以这个函数指针类型是单态化后的具体类型,满足Eq约束。
而第二个片段里,type Eq = fn(&u32) -> u32没有指定生命周期,相当于默认使用了高阶生命周期,这个抽象类型没有实现Eq,所以代码就不符合约束了。
额外补充
Rust的设计逻辑里,只有当一个类型的所有参数(包括类型参数、生命周期参数)都被明确为具体值时,才会为它实现Eq这类需要确定内存表示的trait。函数指针也不例外——泛型参数(包括未绑定的生命周期)会让它变成一个抽象的“类型模板”,而非可比较的具体类型。
内容的提问来源于stack exchange,提问作者Emoun
相关产品推荐
相关产品推荐

