Rust的类型推断如何跨多个语句进行工作?

21

Rust在相当复杂的情况下执行类型推断。有人能否解释(或引导)描述哪些内容可以和不能被推断的规则?

第一个规则很简单:绑定的类型是被绑定表达式的类型:

let n = 10u32;

// Same as:
//   vvvvv
let n: u32 = 10u32;

这个例子让我更加惊奇:右侧的泛型参数可以从左侧的绑定类型中推导出来:

let n: u32 = "10".parse().unwrap();

// same as:            vvvvvvv
let n: u32 = "10".parse::<u32>().unwrap();

这也适用于通用类型的“成员函数”:

let b = Box::new(10u32);

// same as:
//        vvvvv      vvvvvvv
let b: Box<u32> = Box::<u32>::new(10u32);

但最奇怪的是跨语句类型推断:

let v = Vec::new();   // no type!
v.push(10u32);        // apparently v is Vec<u32>?!
// v.push(10i32);     // type error

类型推断和类型推导的规则是什么?


它基于Hindler-Milner。实现方法在https://github.com/rust-lang/rust/blob/master/src/librustc/infer/README.md中有解释,但它已经过时了(仍然使用pre-1.0语法)。 - kennytm
@kennytm:HM 没有“语句”的概念,对吗?那这如何解释 vec! 这样的东西呢? - Kerrek SB
HM确实有let x = e₁ in e₂ - kennytm
@KerrekSB:我一直认为它基本上是一个约束求解器(加上一些“Deref”奖励);我担心试图更精确地指出它可能会在未来过时。 - Matthieu M.
@MatthieuM.:是的,我可以看出它在实践中起作用,只要它试图找出唯一有意义的类型分配方式,但我无法在任何地方找到系统性的处理方法。像 Box :: new(5) 这样的代码随处可见,但从未说明为什么会起作用。 - Kerrek SB
1个回答

12

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