【问题标题】:How does Rust's type inference work across multiple statements?Rust 的类型推断如何跨多个语句工作?
【发布时间】:2021-01-01 12:41:52
【问题描述】:

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。该实现在 github.com/rust-lang/rust/blob/master/src/librustc/infer/… 中进行了解释,但它已经过时了(仍然使用 1.0 之前的语法)。
  • @kennytm:HM 没有“声明”的概念,是吗?这如何解释像 vec! 这样的事情?
  • HM 确实有let x = e₁ in e₂
  • @KerrekSB:我一直认为它基本上是一个约束解决器(加上一些Deref 奖金);恐怕在未来试图更精确地指出它可能会过时。
  • @MatthieuM.: 是的,我可以看到它在实践中有效,只要它试图找出唯一有意义的类型分配,但我找不到系统的处理方法任何地方。像Box::new(5) 这样的代码无处不在,但从来没有在任何地方说明它为什么有效。

标签: rust type-inference


【解决方案1】:

Rust 使用Hindley-Milner 类型系统。它是一组关于根据使用情况建立表达式类型的规则。

可以在这里找到正式的描述和解释:

"What part of Hindley-Milner do you not understand?"

【讨论】:

    猜你喜欢
    • 2019-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-24
    • 2023-03-27
    • 2011-06-20
    相关资源
    最近更新 更多