为什么 Rust 不使用默认的泛型参数类型

20

我希望创建一个具有默认类型的通用结构。但是Rust编译器仍然要求我在创建结构时指定明确的类型。

struct A {}

struct C<T = A> {
    t: Option<T>
}

fn main() {
    let c = C { t: None };
}

Rust编译器显示以下错误:
error[E0282]: type annotations needed for `C<T>`
 --> src/main.rs:8:9
  |
8 | let c = C { t: None };
  |     -   ^ cannot infer type for `T`
  |     |
  |     consider giving `c` the explicit type `C<T>`, where the type parameter `T` is specified

如何允许我的代码用户省略泛型参数?

如果你想建立一个struct而不让用户受到通用类型的干扰,你应该使用构建器模式。 - Boiethios
4
编译器在这里无法确定 T 的类型是默认类型,因为它试图从右侧推断类型。您可以使用这个简单的提示来帮助它: let c:C = C { t: None }; - Denys Séguret
1个回答

13

当您在变量绑定中(赋值的左侧)没有明确指定类型时,编译器必须推断类型。

在这里,该值不够精确(None 可以是任何东西)。

解决方案是在绑定中声明类型。如果只写 C,则无需为 T 指定类型,将应用默认类型:

let c: C = C { t: None };

这是有争议的

  • 它是否是编译器错误(我认为不是,但可以争论人类在此处看不到歧义)
  • 它是否应该修复(我认为不应该,因为更复杂的情况可能会存在歧义或难以辨认,当存在多个推断位置时)

请注意,在中根本没有类型推断:省略<_><SomeType>表示应用默认类型。


我非常确定这不是一个错误。在实际情况下(即c实际被使用的情况下),这种情况不太可能发生。 - Peter Hall
@PeterHall 我也倾向于认为“修复”它会干扰逻辑,也会使人类在不太琐碎的情况下更难解读代码。 - Denys Séguret
谢谢!尽管仍不清楚编译器为什么可以在左表达式中推断T = A,但在右表达式中却无法这样做。 - Michael Ilyin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接