默认的通用实现中可能存在错误?

Possible bug in generic implementation of Default?

给定以下结构 Foo<T> 派生 Default:

#[derive(Default)]
struct Foo<T> {
    bar: Option<T>,
}

为什么编译

fn create<T>() -> Foo<T> {
    Foo {
        bar: Option::default(),
    }
}

但这不是吗?

fn create_alt<T>() -> Foo<T> {
    Foo::default()
}

在我看来,它们都在做完全相同的事情——如果 T 实现了 Default(这是编译器希望我指定的),那应该无关紧要,因为 Option<T> 实现 Default

Here 是 Rust 游乐场的 link 这个例子。

这是一个已知问题,很难修复。 Issue #26925

简而言之,#[derive] 使用了不正确的边界:它假设为了 Foo<T> 实现 DefaultT 必须是 Default,当实际上 Option<T>: Default 就足够了。

修复它的问题是可能有私有类型的结构成员,并且在具有私有成员的 public 泛型结构上使用 #[derive] 可能会部分公开该私有接口。例如,

trait MyTrait {}

struct MyType<T> {}

impl<T> Default for MyType<T> where T: MyTrait {}

#[derive(Default)]
pub struct PubType<T> {
    member: MyType<T>,
}

如果 #[derive(Default)] 做了正确的事情,你实际上有这个 impl 块用于公开私有特征的 public 类型:

impl Default for PubType<T>
    where T: MyTrait
{ ... }

现在解决这个问题的最好方法可能是避免在这种情况下使用 #[derive] 并自己编写 impl