Rust 1.25.0中的以下有效代码段如下:
use std::marker::PhantomData;
trait Foo {
type Eq: Eq;
}
struct Bar<'a>(PhantomData<&'a u8>);
impl<'a> Foo for Bar<'a> {
type Eq = fn(&'a u32) -> u32;
}
如您在Rust Playground上所见,这表明Eq
适用于fn(&'a T) -> T
。
如果我们做出非常小的更改,删除相关类型的生命周期:
use std::marker::PhantomData;
trait Foo {
type Eq: Eq;
}
struct Bar<'a>(PhantomData<&'a u8>);
impl<'a> Foo for Bar<'a> {
type Eq = fn(&u32) -> u32;
}
我们可以看到,
fn(&u32) -> u32
没有实现Eq
: 请查看。error[E0277]: the trait bound `for<'r> fn(&'r u32) -> u32: std::cmp::Eq` is not satisfied
--> src/main.rs:9:10
|
9 | impl<'a> Foo for Bar<'a> {
| ^^^ the trait `std::cmp::Eq` is not implemented for `for<'r> fn(&'r u32) -> u32`
|
= help: the following implementations were found:
<extern "C" fn(A) -> Ret as std::cmp::Eq>
<unsafe fn(A) -> Ret as std::cmp::Eq>
<extern "C" fn(A, ...) -> Ret as std::cmp::Eq>
<unsafe extern "C" fn(A, ...) -> Ret as std::cmp::Eq>
and 2 others
这是故意的吗,还是疏忽了应该实现的内容,或者是一个错误?
从 fn
的源代码来看,他们使用原始指针等价性实现 PartialEq
,也就是说,如果地址相同,则必须是相同的函数。那为什么对于 fn(&T) -> T
不能成立呢?
对我提出的一种选择是, fn(&T) -> T
是针对参数的生命周期进行泛型化处理,因此在逻辑上无法成为 Eq
。而 fn(&'a T) -> T
不是通用的,因为生命周期已被指定为'a
。但我不太确定我是否接受/理解这个假设,所以如果有人有一个好的论点,我也会接受。
fn(&'a T) -> T
不是泛型的” — 是的,它是。'a
是一个泛型生命周期参数。因此,这种推理似乎站不住脚。 - Shepmaster