是故意为fn(&'a T) - > T而不是fn(&T) - > T实现cmp :: Eq?

Ema*_*oun 6 rust

在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;
}
Run Code Online (Sandbox Code Playgroud)

正如在操场上看到的那样,这表明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;
}
Run Code Online (Sandbox Code Playgroud)

我们可以看到Eq是不是为实现fn(&u32) -> u32:

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
Run Code Online (Sandbox Code Playgroud)

这是故意的,疏忽,应该实施,还是一个错误?如果是第一个,那么不这样做的原因是什么?

查看源代码fn,我们看到它们PartialEq使用原始指针等价实现,即如果地址相同,则它必须是相同的函数.为什么这不适合fn(&T) -> T

提交给我的一个选项fn(&T) -> T是在参数的生命周期内是通用的,因此不能在逻辑上Eq.fn(&'a T) -> T不是通用的,因为生命周期已被指定为'a.我不太确定我是否接受/理解这个假设,所以如果有人对此有充分的论据,我也会接受.

Jmb*_*Jmb 2

可能是因为当您比较两个时fn(&T) -> T,您实际上是在比较一个fn(&'a T) -> T与一个fn(&'b T) -> T,无法检查生命周期'a'b是否相同,而当您比较两个时fn(&'a T) -> T,您知道生命周期是相同的。

注:这只是我的猜测,我没有这方面的权威信息。