Go 語言中的函式是程式碼組織和複用的基礎,函式的定義和呼叫非常簡單明瞭。下面是 Go 語言中函式的基礎語法和一些關鍵概念:
函式的定義
在 Go 語言中,函式的定義包括函式名、引數列表、返回值型別和函式體。語法格式如下:
func 函式名(引數列表) 返回值型別 { 函式體 }
示例
下面是一個簡單的函式示例,該函式接收兩個整數引數並返回它們的和:
package main import "fmt" // 定義一個函式 add,接收兩個整數引數 a 和 b,返回它們的和 func add(a int, b int) int { return a + b } func main() { // 呼叫 add 函式,並將返回值賦給 sum sum := add(3, 4) fmt.Println("3 + 4 =", sum) // 輸出:3 + 4 = 7 }
引數和返回值
-
多個引數:如果引數列表中有多個引數,它們之間用逗號分隔。如果多個引數的型別相同,可以省略重複的型別宣告:
func add(a, b int) int { return a + b }
-
多個返回值:Go 語言支援函式返回多個值:
func swap(x, y string) (string, string) { return y, x } func main() { a, b := swap("hello", "world") fmt.Println(a, b) // 輸出:world hello }
命名返回值
函式的返回值可以命名,這樣可以在函式體中直接使用這些變數,並在函式末尾使用 return
語句返回:
func split(sum int) (x, y int) { x = sum * 4 / 9 y = sum - x return } func main() { a, b := split(17) fmt.Println(a, b) // 輸出:7 10 }
空白識別符號 _
如果函式返回多個值,但你不需要使用其中的某些值,可以使用空白識別符號 _
忽略它們:
func foo() (int, int, int) { return 1, 2, 3 } func main() { a, _, c := foo() fmt.Println(a, c) // 輸出:1 3 }
可變引數
Go 語言支援可變引數函式,即函式引數的個數可以是可變的。語法是使用省略號 ...
表示可變引數:
func sum(numbers ...int) int { total := 0 for _, number := range numbers { total += number } return total } func main() { fmt.Println(sum(1, 2, 3)) // 輸出:6 fmt.Println(sum(1, 2, 3, 4)) // 輸出:10 }
小結
- 函式是 Go 語言中程式碼複用的基本單位。
- 函式可以有多個引數和返回值。
- 函式引數和返回值可以命名,增加程式碼的可讀性。
- 可變引數函式可以接收任意數量的引數。
透過理解這些基本語法,可以在 Go 語言中更有效地定義和使用函式。
課程案例
實現加減乘除
package main import "fmt" func eval(a, b int, op string) int { switch op { case "+": return a + b case "-": return a - b case "*": return a * b case "/": return a / b default: panic("unsupported operation" + op) } } func main() { fmt.Println(eval(1, 2, "+")) }
執行結果:
取餘操作
func div(a, b int) (int, int) { return a / b, a % b } func main() { fmt.Println(div(10, 2)) fmt.Println(div(10, 3)) }
寫法二:
package main import "fmt" func div(a, b int) (quotient, remainder int) { return a / b, a % b } func main() { quotient, remainder := div(10, 3) fmt.Println(quotient, remainder) }
兩個返回值只想要一個的情況:
case "/": quotient, _ := div(a, b) return quotient
處理非法制報錯操作
package main import "fmt" func eval(a, b int, op string) (int, error) { switch op { case "+": return a + b, nil case "-": return a - b, nil case "*": return a * b, nil case "/": quotient, _ := div(a, b) return quotient, nil default: //會中斷執行 //panic("unsupported operation" + op) return 0, fmt.Errorf("unsupported operation: %s", op) } } func div(a, b int) (quotient, remainder int) { return a / b, a % b } func main() {
if result, err := eval(1, 2, "x"); err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println(result)
}
}
執行結果:
nil
是一個預定義的識別符號,表示函式呼叫成功且沒有錯誤發生。具體來說,nil
是 error
型別的零值,表示沒有錯誤。讓我們詳細解釋一下 nil
在你的程式碼中的作用。
nil
在 eval
函式中的作用
定義了一個名為 eval
的函式,這個函式接受兩個整數 a
和 b
以及一個字串 op
(表示運算子),然後根據運算子執行相應的算術運算。函式返回一個整數結果和一個 error
型別的值。
在這個函式中:
-
return a + b, nil
等等:- 當運算子是
"+"
、"-"
、"*"
或"/"
時,函式返回計算結果和nil
。這裡的nil
表示沒有錯誤發生。例如,return a + b, nil
意味著加法操作成功,沒有錯誤。
- 當運算子是
-
return 0, fmt.Errorf("unsupported operation: %s", op)
:- 如果運算子不在支援的範圍內(即既不是
"+"
、"-"
、"*"
也不是"/"
),函式返回0
和一個error
型別的值,表示發生了不支援的操作錯誤。fmt.Errorf
建立一個帶有格式化字串的error
物件。
- 如果運算子不在支援的範圍內(即既不是
nil
的意義
在 Go 語言中,函式通常使用返回值 error
來表示函式是否成功執行。如果 error
返回 nil
,則表示函式成功執行,沒有發生錯誤。如果 error
返回非 nil
的值,則表示函式執行過程中發生了錯誤。透過這種方式,Go 語言避免了使用異常處理錯誤。
運算方法重寫案例
package main import ( "fmt" "math" "reflect" "runtime" ) func apply(op func(int, int) int, a, b int) int { p := reflect.ValueOf(op).Pointer() opName := runtime.FuncForPC(p).Name() fmt.Printf("Calling function %s with arguments"+"(%d, %d)\n", opName, a, b) return op(a, b) } func pow(a, b int) int { return int(math.Pow(float64(a), float64(b))) } func main() { fmt.Println(apply(pow, 3, 4)) }