本節介紹倉頡的變量與常量。其中變量又可以細分為不可變變量及可變變量。使用let關鍵字聲明不可變變量,使用var關鍵字聲明可變變量。
本節示例可以在“variable_demo”應用下找到。
不可變的變量
在倉頡裏,使用let關鍵字聲明不可變(immutable)變量,這有點反直覺,比如下面的例子:
// 聲明不變量a,並初始化值1
let a = 1;
println("a: ${a}");
// 錯誤!不能對不可變變量a二次賦值
a = 2;
上述例子:
- 用
let關鍵字聲明瞭不可變變量a,並初始化值1; - 試圖將變量a,重新賦值為2.
但這個例子無法通過倉頡編譯器的校驗,會得到如下的錯誤提示:
error: cannot assign to immutable value
==> main.cj:9:5:
|
9 | a = 2;
| ^^^^^
|
note: variable 'a' is immutable
==> main.cj:4:9:
|
4 | let a = 1;
| ^
|
1 error generated, 1 error printed.
上面的錯誤信息已經指出錯誤的原因是“cannot assign to immutable value”,意味着不能對不可變變量a進行二次賦值。
1. 那麼為什麼要將變量設計為不可變呢?
那“不可變的變量”那還能叫變量嗎?
倉頡設計者認為變量默認不可變,是倉頡的優勢之一,可以充分利用倉頡提供的安全性和簡單併發性來編寫代碼。當然,你仍然有機會使用可變的變量。
2. 什麼是變量?
如果你初次學習編程語言,變量會是一個比較抽象的概念。以倉頡語言來説,聲明一個變量就是申請一塊內存,內存的大小由變量的類型決定,類型會在後續的章節介紹。
比例上面的例子中:
let a = 1;
使用let關鍵字聲明一個變量a,同時把1存放到變量裏面。此時,我們可以説變量中存儲了1,也可以説這塊內存中存儲了1。這裏我們並沒有聲明變量a的數據類型,倉頡會自定根據變量值來推導出a的數據類型,這與很多動態語言的行為相似。
具體怎麼來理解呢?
內存就像這個雞蛋收納盒(如下圖2-1所示),我們為每一個蛋格編碼(這個編碼就相當於內存地址)。聲明一個變量a,相當於找到一個空格把它叫做a,同時把雞蛋放到這個空格里面。我們可以把任何一個空格叫做a,它不過是為蛋格的編碼起了一個別名。把1賦值給變量a的過程稱為“變量綁定”。
3. 未使用的變量
如果你創建了一個變量卻不在任何地方使用它,倉頡編譯器通常會給你一個警告,因為這可能會是個bug。比如下面例子
// 聲明未使用的變量c,並初始化值1
let c = 1;
// 告警!c沒有任何地方用到
變量c沒有任何地方使用,編譯階段就會警告,信息如下:
warning: unused variable:'c'
==> main.cj:13:9:
|
13 | let c = 1;
| ^ unused variable
|
# note: this warning can be suppressed by setting the compiler option `-Woff unused`
1 warning generated, 1 warning printed.
可變的變量
在倉頡裏面,使用var關鍵字聲明可變變量。比如下面的例子:
// 聲明可變變量b,並初始化值1
var b = 1;
println("b: ${b}");
// 修改變量b的值為2
b = 2;
println("b: ${b}");
上述例子執行之後輸出內容如下:
b: 1
b: 2
常量
使用關鍵字const來聲明常量(constant)。類似於不可變變量,常量的值是不允許改變的,下面是一個聲明常量的例子:
// 聲明常量ONE_DAY_IN_SECONDS,並初始化值
const ONE_DAY_IN_SECONDS = 60 * 60 * 24;
println("ONE_DAY_IN_SECONDS: ${ONE_DAY_IN_SECONDS}");
上述例子,聲明瞭常量ONE_DAY_IN_SECONDS,它的值被設置為60(一分鐘內的秒數)乘以60(一小時內的分鐘數)再乘以24(1天的小時數)的結果。倉頡對常量的命名約定是在單詞之間使用全大寫加下劃線。編譯器能夠在編譯時計算一組有限的操作,也就是常量表達式。常量表達式使我們可以以更容易理解和驗證的方式寫出常量值,而不是直接將常量設置為86400。
上述例子執行之後輸出內容如下:
ONE_DAY_IN_SECONDS: 86400
1. 不可變變量和常量什麼區別
既然不可變變量是不可變的,那是否就等同於常量了呢?常量與變量還是有一些區別:
- 聲明常量使用const關鍵字而不是let。
- 常量可以在任何作用域中聲明,包括全局作用域,這在一個值需要被很多部分的代碼用到時很有用。
- 常量只能被設置為常量表達式,而不可以是其他任何只能在運行時計算出的值。
2. 常量的使用場景
在聲明它的作用域之中,常量在整個程序生命週期中都有效,此屬性使得常量可以作為多處代碼使用的全局範圍的值,例如一個遊戲中所有玩家可以獲取的最高分或者光速。
在實際使用中,最好將程序中用到的硬編碼值都聲明為常量,對於代碼後續的維護有莫大的幫助。如果將來需要更改硬編碼的值,你也只需要在代碼中更改一處即可。
參考引用
- 免費開源書《跟老衞學倉頡編程語言開發》
- 免費開源書《跟老衞學HarmonyOS開發》
- HarmonyOS NEXT+AI大模型打造智能助手APP(倉頡版)(視頻)
- 倉頡編程從入門到實踐(北京大學出版社)