rust的变量声明大体分为三类:常量、变量和不可变量。
常量
常量很容易理解,运行过程中不可被改变的值就是常量,js中也有,声明方式差js里面的也差不多:
const THREE_HOURS_IN_SECONDS: u32 = 60 * 60 * 3;
上面代码就声明了一个常量。简单解读下,const是常量声明的关键字,THREE_HOURS_IN_SECONDS是常量名,“:u32”则声明了常量类型是32位无符号整数,不难理解。
但是和js中不同的是(重点,圈起来要考),rust中的常量只允许被赋值成运行前就已经是一个明确值的表达式,简单来讲就是,如果你的常量依赖某个变量,那么就不允许被声明成常量。
举个例子:
let a = 12;
const b: i32 = 12 * a;
上面的代码在js中是合法的,但是在rust则不行,因为常量b依赖了a。但是a如果也是个常量,则是合法的,如下例:
const a:i32 = 12;
const b: i32 = 12 * a;
不可变量
和js不同的是,除了常量之外,rust还引入了不可变量这个概念。
let a = 12;
a = 14
上面这段代码在js中是非常常见的,但是在rust中却会报下面的异常:
因为默认在rust中,你声明的就是不可变量,无法对其重新赋值。 区别于常量,rust中的不可变量的结果允许你在运行时根据可变的结果计算得出。这也就是说:
let a = 12;
let b = 12 * a;
这样是合法的。而这个例子我们之前在讲常量的时候说过,会报异常。
不可变量和js中的常量类似,但是又有些不同,这个我们后面再讲。
变量
到这里,很多人会问了,那么如果我想在rust中声明变量该怎么做呢,让我们看下面这行代码:
let mut a = 12;
a = 14
通过mut关键字,我们就可以声明常规的变量了。但是记住一点,我们虽然在声明的时候都没有指定变量类型,但是rust根据你的赋值推断出变量类型,且变量在被重新赋值的过程中,不允许改变变量类型。 这点也是和js中有着很大不同的一点。
我们也可以显式的指明变量类型。例如:
let a:i32 = 12;
let mut b:i32 = 12 * a;
重影(Shadowing)
刚刚我们提到rust的不可变量和js的常量类似,但是又有不同,这个不同,就是重影(有的也叫变量遮蔽)。看下面这段代码:
let a:i32 = 12;
let a:i32 = 14;
上面这段代码在js中必然是不合法的,但是在rust中却是合法的。这就是rust中重影的概念,相当于重新声明了一次a,且重新声明的过程中,你可以随意的改变a的类型和值。
let a:i32 = 12;
let a:String = String::from("hello world");
也是ok的。
命名规则
本来文章到这里也该结束了,但是想了想还是简单的讲下rust变量命名规则吧。
所以语言的变量命名规则其实都大同小异:不能使用保留字;不能用数字开头;不能使用标点、空格等特殊符号等。
除此之外,在rust中声明了一个不会被使用的变量,rust将会抛出警告,如果你一定要声明它(可能是为了留着以后扩展等原因),你可以用“_”开头,这样rust编译的时候就会忽略它而不出给警告。例如:
let _a:i32 = 12;
这条规则如果熟悉ts的同学应该很容易理解。
刚开始接触rust中不可变量和重影的概念的时候,其实会有些不习惯,但是如果你站在性能和安全的角度去想,一切似乎又是那么的自然。常量可以提高安全性,但是有时候重复声明,又会造成内存开销,所以又需要变量。作为一个性能和安全都需要的语言,rust创造性的提出了不可变量、变量和重影等一系列概念,不可谓不强。
不知道你服不服,反正我是服的😁。