函數地址指向函數本身的內存地址,而指針指向變量或結構的內存地址。然而,函數地址也可以存儲在指針中,使我們能夠通過指針調用函數。這些概念在各種場景中很有用,例如動態調用函數或創建回調函數。
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)) }
登錄后復制
此示例演示了如何將函數地址存儲在字典中,并在運行時通過函數名稱動態調用它們。