我对Rust感兴趣,所以我开始阅读Rust网站上的Rust编程指南,发现变量是按以下方式声明的:
let x: i32 = 5;
这意味着将值整数5赋值给变量类型整数32位,从这一点起,它将由符号x
引用。
我的主要问题是为什么let
关键字根本就存在?这似乎是多余的,好像它实际上并没有“做”任何事情。
我假设编译器能够告诉以下是变量(或const变量)声明:
x: i32 = 5;
似乎没有let
关键字的原因,但可能 是一个明智的原因,因为Rust专注于安全性。那是什么原因?
编辑:添加:作为函数参数,不需要let关键字。这是一个例子:
fn add1(x: i32) -> i32
{
x = x + 1
}
这看起来有点奇怪 - 由于缺少let
,这个“看起来像”是一个参考传递。但事实并非如此。这是价值的传递。 (或者至少我认为是。)这是句法上的不一致吗?
顺便说一句,我会发现改变这个陈述并写下来更合乎逻辑:
i32 x = 5;
如果你愿意,可以在那里放一个冒号:
i32: x = 5;
我想我会发现更合乎逻辑的原因是:
也许有些人认为反过来?但这让我想到另一点;如何在Rust中声明几个相同类型的变量?如:
let x, y, z: i32 = {4, 5, 5} // A guess of what this might look like?
或者这只是Rust中不允许的?
答案 0 :(得分:33)
Rust具有本地类型推断,因此通常不需要写入类型; let x = 5;
就足够了。 x = 5;
会有很大不同,因为它不会声明变量x
,而Rust非常故意将声明和赋值分开。
它实际上也是let PATTERN = EXPR;
,而不只是let IDENT = EXPR;
,因此删除let
关键字会导致语法模糊。模式可以是mut x
(使变量绑定变为可变),它可以是(a, b)
表示元组解包,& c。
你只认为i32 x = 5;
有意义,因为你已经习惯了像C ++这样的语言。说真的,谁提出了这个想法?在纯粹的哲学理由中,在名称之后使用类型比以前更有意义,只有声明变量的类型也是愚蠢的。各种各样的语法模糊。类型推断,允许你完全省略类型,是一个更好的方法。
答案 1 :(得分:11)
首先,解析模糊性。虽然可能可以解析这样的代码(但只是因为a < b > c
因为不同的原因而已经非法表达),它会使所有工具复杂化并使解析器性能(和错误恢复)差。
其次,输入推理。无论何处写入类型,都可以省略,因此您需要let
或其他标记来区分赋值和声明。 (你可以在技术上使用let x = ...;
和Type x = ...;
,但为什么?它不是一种类型,它是一种类型的缺席。)
let
适用于任何(无可辩驳的)模式,包括那些兼容完美合法表达式的模式:StructLiteral { field: x, other_field: y }
和Some(thing)
。如果不是解析器(它当前拒绝Some(a) = b
),那么对于人类来说,这是更加含糊不清的根源。
第四,虽然你可能习惯type name
,但name: type
有悠久的传统,而且没有Rust&#39;它正在获得主流牵引力。做(例如在Scala中)。
第五,我对此提出异议:
编程时,你通常知道&#34;键入&#34;在你想到它的名字之前你想要的数据。
也许我知道数据的一般形状(整数,字符串,迭代器,集合等),但确切的类型通常是第二个实现细节。在类型推断面前,这种说法也会分崩离析:如果你最常想的是什么,那么如何将这种类型排除在外呢?另一方面,如果您只是在谈论编写代码时首先想到的内容,那么案例就会被驳回:代码的读取频率远远高于编写代码,而且顺序是引入哪些概念不需要(通常也不应该)反映它们被构思的顺序。
答案 2 :(得分:9)
它显着简化了语法。请记住,左侧有一个完整的模式,它实际上不是let var
它是let pattern
。
如何在Rust中声明几个相同类型的变量?
这是一个完全不同的问题,但没有直接的方法可以做到这一点,不,至少不是你想的那样。你可以
let (a, b, c) = (1, 2, 3);
但是他们 属于同一类型,这是一种解构模式。