函數地址指向函數本身的內存地址,而指針指向變量或結構的內存地址。然而,函數地址也可以存儲在指針中,使我們能夠通過指針調用函數。這些概念在各種場景中很有用,例如動態調用函數或創建回調函數。
Go中的函數地址與指針:微妙的關系
Go語言中,函數地址和指針看似相近,但它們之間卻存在著微妙的區別。理解它們的差異對于編寫高效且可維護的代碼至關重要。
函數地址
函數地址是指向函數本身內存位置的地址。它可以通過編譯器生成的 func 字面字或 reflect 包中的 ValueOf 或 Func 函數獲取。
指針
指針是一個存儲另一個值地址的變量。在Go中,指針可以通過 * 符號和類型名稱聲明。例如,*int 是一個指向整數值的指針。
它們之間的關系
函數地址和指針指向不同的東西。函數地址指向函數本身的內存地址,而指針指向變量或結構的內存地址。但是,函數地址也可以存儲在指針中。
在以下示例中:
func myFunc() {}
var fptr = &myFunc
登錄后復制
fptr 是一個指針,指向函數 myFunc 的地址。這使我們能夠通過指針調用函數:
(*fptr)() // 等同于 myFunc()
登錄后復制
實戰案例
函數地址和指針在各種場景中很有用。以下是一個利用這些概念的實用案例:
package main
import (
"fmt"
"math"
)
// 計算半徑的函數
func radius(n int) float64 {
return float64(n) / 2.0
}
// 求一個數字的根的函數
func sqrt(n int) float64 {
return math.Sqrt(float64(n))
}
var operations = map[string]func(int) float64{
"radius": radius,
"sqrt": sqrt,
}
func main() {
input := "sqrt"
num := 9
// 通過名稱獲取函數指針
op := operations[input]
// 調用函數并打印結果
fmt.Println(op(num))
}
登錄后復制
此示例演示了如何將函數地址存儲在字典中,并在運行時通過函數名稱動態調用它們。






