【问题标题】:Why do I have to specify the type for "const" variables but not for "let" variables?为什么我必须为“const”变量指定类型而不为“let”变量指定类型?
【发布时间】:2019-08-27 03:11:42
【问题描述】:

要在 Rust 中创建变量,您可以使用:

let var_name = 10;

这也是有效的:

let var_name: i32 = 10;

常量变量是这样创建的:

const VAR_NAME: i32 = 10;

但是如果你尝试像这样创建一个常量变量:

const VAR_NAME = 10;

您会收到如下所示的错误:

error: expected `:`, found `=`
 --> src/main.rs:5:11
  |
4 |   const VAR_NAME = 10;
  |                 ^ expected `:`

我来自 JavaScript、Python 和 PHP 等语言,这让我有点困惑。

为什么在使用const时必须指定类型定义,而在使用let时却不需要?

【问题讨论】:

    标签: variables types rust constants


    【解决方案1】:

    目前,有一个rule“必须显式键入常量。” (对于static:“静态项类似于常量”)。

    但是,你是对的:编译器可以推断它。对此进行了公开讨论:#1349, TL;DR:

    • 我们可以从技术上推断出conststatic 变量的类型
    • 我们不经常使用它们,因此注释类型并不是很烦人
    • 我们或许应该将常量/静态的类型推断限制为仅字面值
    • 这可能会降低错误消息的准确性
    • 可能会将常量/静态变量的类型推断限制在函数体等局部范围内
    • 对于整数,const FOO = 22 会推断为i32,因此可能不是人们期望的类型。所以我们最终会写const FOO = 22usize
    • 使用const-fn 初始化变量时,应推断类型
    • 当变量用另一个显式类型的变量初始化时
    • 对于数组,显式类型非常多余
    • 对于仅导出的变量,我们最终可能无法推断其类型(因此会出现编译时错误“需要指定类型”)

    值得一提的是,Rust 中类型推断的指导原则之一是类型推断应该是本地的。这就是为什么与 Haskell 不同,函数签名总是需要完全指定的原因。造成这种情况的原因有很多,特别是这意味着人类读者更容易推理和更好的错误消息。这使得模块级别 const 在推理方面处于困境。 Matthieu M.

    到目前为止,还没有提议的 RFC,所以这个问题保持开放。

    另见:

    【讨论】:

    • 为什么不关闭为 dup ?因为另一个问题是关于本地范围(将让未来的读者)
    • @Stargateur 感谢您抽出时间并努力回答这个问题,非常感谢。
    • 不错的总结。值得一提的是,Rust 中类型推断的指导原则之一是类型推断应该是local。这就是为什么与 Haskell 不同,函数签名总是需要完全指定的原因。造成这种情况的原因有很多,特别是这意味着人类读者更容易推理和更好的错误消息。这使得模块级别 const 在推理方面处于困境。
    • consts 在函数中根本不是变量。它们是项目。与let 绑定不同,它们不存在于函数范围内,除了语法。例如,函数内部的consts 可以不使用封闭函数的泛型参数。在此他们与嵌套的fns 共享行为。至于推理的局部性,请注意 Rust 对 impl Trait 使用了全局类型推理,它们是真正“健忘”的推理变量。
    • 感谢您抽出宝贵时间撰写此摘要,我删除了我之前的评论,因为它不再相关 =) - 祝您度过愉快的一天!
    猜你喜欢
    • 2016-03-26
    • 2021-11-08
    • 1970-01-01
    • 1970-01-01
    • 2021-08-28
    • 1970-01-01
    • 2016-11-08
    • 1970-01-01
    • 2018-09-01
    相关资源
    最近更新 更多