博客 / 詳情

返回

跟老衞學倉頡編程語言開發:變量與常量

本節介紹倉頡的變量與常量。其中變量又可以細分為不可變變量及可變變量。使用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(倉頡版)(視頻)
  • 倉頡編程從入門到實踐(北京大學出版社)

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.