[Golang] function & method 函式與方法
函式宣告
最常見的宣告方式
使用 func
來定義函式:
// 完整寫法:func add(x int, y iny) int {...}
func add(x, y int) int {
return x + y
}
使用 expression 方式定義
也可以使用 :=
來定義函式:
func main() {
add := func(x, y int) int {
return x + y
}
}
匿名函式(anonymous function)
常用在 goroutine 或該 function 只會使用一次的情況:
// 定義一個匿名函式並直接執行
func main() {
// 沒有參數
func() {
fmt.Println("Hello anonymous")
}()
// 有參數
func(i, j int) {
fmt.Println(i + j)
}(1, 2)
}
在函式中帶入參數:function with arguments
func deal(product []string, number int) {
// ...
}
函式本身可以是另一個函式參數,也可以是回傳值
在 golang 中,函式本身可以是另一個函式的參數:
// cb 這個參數是一個函式
func cycleNames(names []string, cb func(string)) {
for _, name := range names {
cb(name)
}
}
func sayBye(name string) {
fmt.Printf("Goodbye %v \n", name)
}
func main() {
names := []string{"Aaron", "John", "Kelly"}
// 在參數中帶入函式
cycleNames(names, sayBye)
}
範例二:
// compute 這個函式可接收其他函式作為參數
func compute(fn func(float64, float64) float64) float64 {
return fn(3, 4)
}
func main() {
// sqrt(a^2 + b^2)
hypot := func(x, y float64) float64 {
return math.Sqrt(x*x + y*y)
}
fmt.Println(compute(hypot)) // 5, hypot(3, 4)
fmt.Println(compute(math.Pow)) // 81,math.Pow(3, 4)
}
函式也可以在執行後回傳另一個函式(閉包):
func fibonacci() func() int {
// ...
}
範例程式碼:
// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
position := 0
cache := map[int]int{}
return func() int {
position++
if position == 1 {
cache[position] = 0
return 0
} else if position <= 3 {
cache[position] = 1
} else {
cache[position] = cache[position-2] + cache[position-1]
}
return cache[position]
}
}
func main() {
f := fibonacci()
for i := 0; i < 10; i++ {
fmt.Println(f())
}
}
適用閉包(closure)的概念
在 golang 的函式同樣適用閉包的概念,可以利用閉包把某個變數保留起來:
func adder() func(int) int {
sum := 0
return func(x int) int {
sum += x
return sum
}
}
func main() {
// pos 中的 sum 和 neg 中的 sum 是不同變數
pos, neg := adder(), adder()
for i := 0; i < 10; i++ {
fmt.Println(pos(i), neg(-2*i))
}
}