Rust 程式設計:運算子

本章介紹運算子,這些運算子是 Rust 中實際執行工作的基礎元件。運算子間可相互組合,達到更複雜的效果。

Rust 包括以下運算子:

  • 代數運算子
  • 二元運算子
  • 比較運算子
  • 布林運算子
  • 轉型運算子
  • 指派運算子
  • 複合指派運算子
  • 其他運算子

本章將逐一介紹這些運算子。

代數運算子

包括加 +、減 -、乘 *、除 /、取餘數 % 等運算子。見下例:

在本例中,我們使用 assert_eq! 代替 println!,這個函式在程式兩邊不相等時會引發錯誤,好處是由程式替我們檢查值是否正確,而不需人工確認。本書中部分代碼會使用這種風格來表示。

然而,由於電腦的限制,浮點數在電腦內的表示是不精確的。例如,0.3 - 0.2 的結果 不會剛好是 0.1 而有一個微小的誤差。見以下範例:

本程式引發了以下錯誤,表示浮點數的運算是不精確的:

比較好的方法,是比較兩數相減的誤差值,當誤差值的絕對值夠小時,表示條件成立。見以下範例:

本程式即可順利執行。在本程式中,我們使用 assert!,這個函式在其內條件式不為真時引發錯誤,使用方式類似 assert_eq!

二元運算子

包括 bitwise AND &、bitwise inclusive OR |、bitwise exclusive OR ^、左移 <<、右移 >> 等運算子。Bitwise 運算是以二進位數來運算,和平常使用的十進位數不同,有興趣的讀者可參考計算機概論等相關書籍。

比較運算子

對於支援的型別,也可比較其大小。包括等於 ==、不等於 !=、大於 >、小於 <、大於等於 >=、小於等於 <= 等運算子。

布林運算子

布林運算子是用來結合兩個以上的條件式,包括 AND &&、OR || 、NOT ! 等。

AND 運算遵守以下邏輯:

p q Result
true true true
true false false
false true false
false false false

OR 運算遵守以下邏輯:

p q Result
true true true
true false true
false true true
false false false

NOT 運算遵守以下邏輯:

p Result
true false
false true

如果覺得記上述表格很困難,只要記得「所有條件為真時,AND 才為真;只要有條件為真時,OR 即為真」。結合上述基本邏輯,可撰寫更複雜的條件敘述。以下為範例:

轉型運算子

轉型運算子 as 是用來轉換資料的型別。由於 Rust 的安全設計,不能直接用整數和浮點數相互運算,而要透過明確的轉型,這和大部分的程式語言不同。下列程式看似正確:

本程式卻引發了以下錯誤:

這個錯誤訊息,包含一個新的概念。在 Rust,運算子是透過 trait 的機制來達成,若沒有實作相關的 trait,則無法進行相關的運算。我們會在後續的章節介紹 trait。

我們將程式改寫如下:

經過轉型,本程式為 f64 型別間的運算,即可正確執行。

指派運算子

我們已經在前一章看過指派運算子 = 了,在宣告變數時通常也會一併賦值。

注意:不要將指派運算子 = 和相等運算子 == 搞混。

複合指派運算子

複合指派運算子是將代數運算子或二元運子算以及指派運算子合併,簡化程式碼。例如,以下程式碼:

可以簡化為:

其他運算子

這裡列出其他筆者未提到的運算子:

  • 負號運算子 -:將數字的正負號反轉
  • 解參考運算子 *:得到參考所指向的值
  • 參考運算子 & 和 & mut:得到某個值的參考

我們會在後續的章節討論參考 (reference)。

註:Rust 的參考類似 C/C++ 的指標。

運算子優先順序

Rust 運算子的優先順序,由高至低,如下:

筆者不會刻意去記運算子的優先順序。只要在程式碼中減少過度複雜的敘述,即可減少因運算子優先順序造成的混淆。如果某些敘述較複雜,用中括號 () 將運算優先順序提高即可。