RUST 學習日記 第5課 ——變量和常量
說些題外話逗柴,有些同學認為前面那么點內(nèi)容侦铜,啰啰嗦嗦的講了四節(jié),其實不然函卒。本系列課程也是適合0基礎的同學县习,如果您是Rust大神,那么可以忽略本系列的文章谆趾。還有學習一門編程語言要搞明白是為什么躁愿,不能只學習表面』ε睿基礎一旦打好彤钟,學習任何語言都會覺得很容易。俗話說跷叉,萬事開頭難逸雹,一旦前面做好鋪墊,那么后面再難也難不住你云挟。當然本人水平有限梆砸,錯誤和不足之處在所難免,處理問題也有不妥之處园欣,敬請各位大佬帖世,專家批評改正。
0x00 開篇
上一節(jié)咱們了解了Rust的常用規(guī)范沸枯,算是入鄉(xiāng)隨俗了日矫。那么從今天開始就要正式進入Rust的學習了。該系列課程預計100課左右绑榴,大致將分為基礎哪轿,進階,算法翔怎,實戰(zhàn)四大部分窃诉,甚至會更多。課程將會由淺入深的非常細致的講解Rust赤套,帶你深入了解Rust飘痛。該系列教程所用的Rust版本是1.52.1
(截至目前的最新版本)。
0x01 了解變量
Rust語言的變量是一種綁定語義于毙,相當于是把一個變量名和一個值綁定在一起敦冬,從而建立起了關聯(lián)關系,類似于鍵值對唯沮。為了安全性的考慮脖旱,Rust的變量默認是不可以改變的堪遂,當然Rust也提供了另一種變量——可變變量。如果你了解過其它語言萌庆,你會發(fā)現(xiàn)Rust變量的設計與其它語言還是不同的溶褪。
0x02 命名規(guī)范
Rust變量名可以由字母,數(shù)字或者下劃線組成践险。同時還有以下3個限制條件:
- 不能以數(shù)字開頭
- 字母區(qū)分大小寫
- 不能只有下劃線
PS:關于下劃線猿妈,在Rust中式一種標識符,代表“忽略這個變量”巍虫,這里僅了解即可彭则,后續(xù)章節(jié)會詳細介紹。
0x03 不可變變量(Immutable)
在Rust中是通過let
關鍵字來聲明變量的占遥,變量遵循先聲明后使用的原則俯抖。確切的說應該是使用let
將值綁定到變量。Rust 通過靜態(tài)類型確保類型安全瓦胎。變量綁定可以在聲明時說明類型芬萍,當然也可以不說明類型,編譯器則將會從上下文推導出變量的類型搔啊。示例代碼如下:
fn main() {
// 每次聲明變量時柬祠,注意變量命名規(guī)范
// 聲明整數(shù)
let a = 5;
// 布爾值
let b1= true;
// 字符串
let _c = "zhangsan";
// 浮點數(shù)
let d_1 = 123.3;
dbg!(a);
dbg!(b1);
dbg!(_c);
dbg!(d_1);
}
0x04 可變變量(Mutable)
使用let
關鍵字聲明的變量是不可改變的。如果你試圖改變它值负芋,編譯器會報錯漫蛔。Cannot assign twice to immutable variable [E0384]
let x = 5;
// 再次賦值會報錯
x = 15;
這時,如果你想重新對變量賦值示罗,則需要使用mut
關鍵字惩猫,告訴編譯器這個變量是可以重新賦值的。
// 使用mut關鍵字聲明變量
let mut y = 5;
// 編譯器不會報錯
y = 15;
單從變量賦值這一點蚜点,咱們就可以看出Rust的安全性了。增加mut
關鍵字拌阴,可以傳達該變量允許被更改的意圖绍绘,使得代碼可讀性增強,也容易維護迟赃。
0x05 變量遮蔽 (Shadowing)
在Rust中陪拘,允許在同一代碼塊中使用let
關鍵字多次聲明同名變量,如果多次聲明同一變量纤壁,則后者會覆蓋前者的值左刽,因此前者的值將無法再去訪問,多次覆蓋則以最后一次的值為準——這就是變量遮蔽酌媒,有時也叫做變量重定義欠痴。
// 變量遮蔽
let m = 1;
let m = 2.3;
let m = "張三";
let mut m = 4;
let m = 5;
dbg!(m);
最后輸出結果是:
[src\main.rs:37] m = 5
變量遮蔽的實質(zhì)是同let
聲明了一個新的變量迄靠,但是巧合的是與之前聲明的變量重名了。變量遮蔽有以下幾個特點:
- 它們是完全不相同的變量
- 它們所處的內(nèi)存空間不相同
- 它們的值的類型可以不相同
- 它們的值可以不相同
- 可以作用于不可變變量喇辽,也可以作用于可變變量
- 不可以作用于
static
變量 - 不可以作用于
const
常量
在C
掌挚,C++
,Java
等常見的語言中是不存在變量遮蔽的菩咨,因此變量遮蔽常用于一些特殊場景吠式,將會在后續(xù)章節(jié)介紹。
0x06 常量(Const)
常量是指綁定到一個標識符且不允許改變的值抽米,其一旦定義后將沒有任何方法能夠改變它特占。它還有一個非常重要的特點——常量會在編譯時被復制到使用的地方(類似于C語言的#define
)。 當然云茸,這種復制也會發(fā)生在外部包被編譯的場合是目。其聲明語法如下:
// 命名規(guī)則:變量名全部大寫
// 多單詞組合使用下劃線分割,如:MIN_VALUE
// 必須指定變量的數(shù)據(jù)類型
// const PI = 3.141592653; [X] 錯誤寫法
const PI : f64 = 3.141592653;
聲明規(guī)則:
- 使用
const
關鍵字聲明 - 常量的名稱通常都是全部采用大寫字母查辩,如遇到多單詞組合胖笛,則使用下劃線分割,如:MIN_VALUE
- 必須指定變量的數(shù)據(jù)類型(關于數(shù)據(jù)類型將在下節(jié)介紹)
看到這里宜岛,心中是否存在疑問——前面說的不可變變量的值不能被更改长踊,常量的值也不能被更改,那么它們有什么區(qū)別呢萍倡?當然上面也提到了部分區(qū)別身弊,下面整理下完整答案。
- 常量必須使用
const
關鍵字聲明列敲,且必須注明值的類型阱佛,不可變變量使用let
關鍵字聲明。 - 不可變變量可以通過變量遮蔽的方式戴而,讓其值改變凑术。實質(zhì)上是新的變量,只是同名而已所意。然而常量則沒有變量遮蔽的概念淮逊,無法重復定義。常量一旦定義扶踊,就永遠不能變更和重新賦值泄鹏。
- 可以在任何作用域中聲明常量。在聲明它的作用域中秧耗,常量在整個生命周期(關于生命周期將在后續(xù)章節(jié)介紹)中都是有效的备籽。
- 常量智能被賦值為常量表達式或者數(shù)學表達式。不能是函數(shù)的返回值分井,或者是其他在運行時才能確定的值车猬。然而不可變變量則不受限制霉猛。
0x07 靜態(tài)變量——又稱全局變量(Static)
靜態(tài)變量和常量很相似,但是在一個程序中诈唬,靜態(tài)變量擁有精確固定的內(nèi)存地址韩脏,對于靜態(tài)變量的所有引用都指向相同的內(nèi)存地址。靜態(tài)變量也存在生命周期铸磅,但是其生命周期在程序中是最長的赡矢。靜態(tài)變量不會在程序結束時調(diào)用drop
函數(shù)。官方文檔是這樣說的:
A static item is similar to a constant, except that it represents a precise memory location in the program. All references to the static refer to the same memory location. Static items have the lifetime, which outlives all other lifetimes in a Rust program. Static items do not call
drop
at the end of the program.
靜態(tài)變量是可以用mut
來修飾的阅仔,一旦靜態(tài)變量可變吹散,就會出現(xiàn)多線程同時訪問的場景,從而引發(fā)內(nèi)存不安全的問題八酒,因此對于static mut
聲明的變量必須在unsafe
塊中進行定義(有關unsafe
的內(nèi)容將在后續(xù)章節(jié)介紹)空民。
靜態(tài)變量和常量的應用場景:
- 數(shù)據(jù)占有內(nèi)存比較大的場合,推薦使用靜態(tài)變量羞迷。
- 程序需要變量的地址屬性的情況下界轩,推薦使用靜態(tài)變量。
- 變量需要是可變的情況下衔瓮,推薦使用靜態(tài)變量浊猾。
- 其它場景常量優(yōu)于靜態(tài)變量。
fn main (){
static IP: &str = "111.111.111.111";
static mut NAME : &str = "zhangsan";
dbg!(IP);
unsafe {
dbg!(NAME);
}
}
0x08 本節(jié)源碼
005 · StudyRust - 碼云 - 開源中國 (gitee.com)
下節(jié)預告——了解下Rust的常見基本數(shù)據(jù)類型