bells
安裝本網站至主畫面:

[Go][Golang] 程式設計教學:運算子 (Operator)

PUBLISHED ON SEP 10, 2017 — PROGRAMMING
Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Email

    在上一篇文章中,我們介紹了 Go 的變數和資料型別。接著,在本篇文章中,我們會介紹運算子 (operator),運算子如同程式中的基本指令,不同的資料型別可用的運算子各自不同;透過這些基本指令,可以組合出更複雜的功能。

    Go 包含以下運算子:

    • 代數運算子 (arithmetic operator)
    • 二元運算子 (bitwise operator)
    • 關係運算子 (relational operator)
    • 邏輯運算子 (logical operator)
    • 位址運算子 (adress operator)
    • 接收運算子 (receive operator)

    我們將在本文中逐一介紹這些操作子。

    代數運算子

    十進位數字的可用的運算子,就是基本的代數運算,相信大家都已經相當熟悉。Go 的代數運算子如下:

    • a + b:相加
    • a - b:相減
    • a * b:相乘
    • a / b:相除
    • a % b:取餘數

    實例如下:

    package main
    
    func main() {
    	a := 3
    	b := 2
    
    	assert(a+b == 5, "It should be 5")
    	assert(a-b == 1, "It should be 1")
    	assert(a*b == 6, "It should be 6")
    	assert(a/b == 1, "It should be 1")
    	assert(a%b == 1, "It should be 1")
    }
    
    // Home-made `assert` for Go.
    func assert(condition bool, msg string) {
    	if !condition {
    		panic(msg)
    	}
    }
    

    在本例中,我們用自製的 assert 語句取代常見的 fmt.Println,因為前者可以從程式碼中直接看出我們的意圖。當程式可順利執行時,代表程式沒有錯誤。

    浮點數沒有取餘數運算,其他運算和整數相同。另外,在 Go 裡面,除以零會引發程式錯誤,程式設計者需自行檢查及預防。

    二元運算子

    二元運算使用二進位數進行運算,有以下數種運算方式:

    • a & b:bitwise AND,兩者皆為 1 時才為 1
    • a | b:bitwise OR,兩者其中之一為 1 時即為 1
    • a ^ b:bitwise XOR,兩者僅其一為 1 時才為 1
    • a << n:左移
    • a >> n:右移

    以下例子用二元運算模擬系統權限:

    package main
    
    const EXEC = 1  // 0001
    const WRITE = 2 // 0010
    const READ = 4  // 0100
    
    func main() {
    	// Read only
    	assert(READ == 4, "It should be read-only")
    
    	// Read and write
    	assert(READ^WRITE == 6, "It should be both readable and writable")
    
    	// Read and Exec
    	assert(READ^EXEC == 5, "It should be both readable and executable")
    }
    
    // Home-made `assert` for Go.
    func assert(condition bool, msg string) {
    	if !condition {
    		panic(msg)
    	}
    }
    

    二元運算多用於低階程式 (low-level programming),一般情境下較少常用到。雖然 Go 不是真正的系統程式設計 (system programming) 語言,仍保留這項特性。

    關係運算子

    關係運算子是用來比較兩個值之間的大小,Go 有以下關係運算子:

    • a == b:相等
    • a != b:不等
    • a < b:小於
    • a <= b:小於或等於
    • a > b:大於
    • a >= b:大於或等於

    基本上,Go 內建型態都可以相互比較。關係運算子會回傳布林值,主要是用在條件判斷中,我們將於後文介紹條件判斷。

    package main
    
    func main() {
    	a := 5
    	b := 3
    
    	assert((a == b) == false, "It should be false")
    	assert((a != b) == true, "It should be true")
    	assert((a > b) == true, "It should be true")
    	assert((a >= b) == true, "It should be true")
    	assert((a < b) == false, "It should be false")
    	assert((a <= b) == false, "It should be false")
    }
    
    // Home-made `assert` for Go.
    func assert(condition bool, msg string) {
    	if !condition {
    		panic(msg)
    	}
    }
    

    邏輯運算子

    邏輯運算子用來結合數個條件判斷,以達成複合的效果。Go 有以下邏輯運算子:

    • &&:且 (AND)
    • ||:或 (OR)
    • !:否 (NOT)

    一般程式設計書籍會提供真值表 (true value table),但其實不需要記憶那個表格,只要記得:

    • AND (&&):兩者為真為真
    • OR (||):其中之一為真為真
    • NOT (!):真變偽,偽變真

    以下為實例:

    package main
    
    func main() {
    	// and
    	assert((true && true) == true, "It should be true")
    	assert((true && false) == false, "It should be false")
    	assert((false && true) == false, "It should be false")
    	assert((false && false) == false, "It should be false")
    
    	// or
    	assert((true || true) == true, "It should be true")
    	assert((true || false) == true, "It should be true")
    	assert((false || true) == true, "It should be true")
    	assert((false || false) == false, "It should be false")
    
    	// not
    	assert((!true) == false, "It should be false")
    	assert((!false) == true, "It should be true")
    }
    
    // Home-made `assert` for Go.
    func assert(condition bool, msg string) {
    	if !condition {
    		panic(msg)
    	}
    }
    

    邏輯運算子會回傳布林值,同樣也是用於條件判斷中。

    位址運算子

    位址運算子牽涉到指標 (pointer),接收運算子牽涉到通道 (channel),這都是比較進階的概念,我們將於後文介紹。

    運算子優先順序

    不同運算子放在一起時,有一套內定的順序 (precedence),如下:

    Precedence    Operator
    5             *  /  %  <<  >>  &  &^
    4             +  -  |  ^
    3             ==  !=  <  <=  >  >=
    2             &&
    1             ||
    

    但是,不要記這個順序,因為:

    • 代數運算和數學上的運算先後順序相同
    • 撰寫較簡單的敘述,就可避免過於複雜的優先順序
    • 可以用括號改變優先順序,同時可讓程式碼更清晰

    經過本文的說明,相信讀者對運算子已經有相當的概念,日後可用在自己的程式中。在下一篇文章中,我們會介紹控制結構 (control structures),包括條件敘述 (condition) 和迴圈 (loop)。

    你或許對以下產品有興趣
    Xmas tree