L'adresse de la fonction est un pointeur vers le code de fonction et peut être obtenue en utilisant unsafe.Pointer. Les adresses de fonction peuvent être transmises à d'autres fonctions, telles que l'impression des noms de fonctions ou le tri par fonction. Il permet également d'utiliser des assertions de type pointeur de fonction pour vérifier les fonctions qui implémentent une interface spécifique.
Comprenez les secrets des adresses de fonction Go
Introduction
Dans Go, les adresses de fonction sont un outil précieux. Cela nous permet de passer des fonctions par référence, donnant au code une plus grande flexibilité. Cet article analysera en profondeur le mécanisme interne des adresses de fonctions et démontrera son application à travers des cas pratiques.
Essence de l'adresse de fonction
Une adresse de fonction est essentiellement un pointeur qui pointe vers le segment de code de la fonction en mémoire. Comme tout autre pointeur, il prend la forme *T
, où T
est le type de fonction. *T
的形式,其中 T
是函数类型。
获取函数地址
在 Go 中,可以使用 unsafe.Pointer
包中的 Pointer
函数获取函数地址:
import "unsafe" func getFuncAddr(f func()) uintptr { return uintptr(unsafe.Pointer(&f)) }
getFuncAddr
函数接收一个函数作为参数并返回其地址。
传递函数地址
函数地址可以作为参数传递给其他函数。例如,考虑一个打印函数名的函数:
import "fmt" func printFuncName(f func()) { fmt.Println(runtime.FuncForPC(getFuncAddr(f)).Name()) }
printFuncName
接收一个函数并打印其名称。runtime.FuncForPC
函数将函数地址转换为其对应的 *Func
值,从而允许我们访问函数的元数据。
实战案例
排序切片:
我们可以使用函数地址对切片元素进行基于函数的排序:
func sortByFunc(nums []int, compare func(a, b int) int) { sort.Slice(nums, func(i, j int) bool { return compare(nums[i], nums[j]) < 0 }) } func main() { nums := []int{5, 2, 8, 1, 9} sortByFunc(nums, func(a, b int) int { return a - b }) fmt.Println(nums) // 输出: [1 2 5 8 9] }
在这个示例中,sortByFunc
接受一个切片和一个比较函数,然后使用 sort.Slice
根据比较函数对切片进行排序。
函数指针类型断言:
函数指针类型断言允许我们检查函数指针是否实现了特定的接口:
import "fmt" type Stringer interface { String() string } func isStringer(f interface{}) bool { _, ok := f.(func() string) return ok } func main() { fmt.Println(isStringer(func() string { return "Hello" })) // true fmt.Println(isStringer(func() int { return 1 })) // false }
isStringer
函数检查给定接口值是否实现了 Stringer
接口。它使用类型断言来确定接口值是否指向实现 String()
Pointer
dans le package unsafe.Pointer
pour obtenir l'adresse de la fonction : 🎜rrreee🎜 getFuncAddr
Function reçoit une fonction en argument et renvoie son adresse. 🎜🎜🎜Passer l'adresse de la fonction 🎜🎜L'adresse de la fonction peut être transmise en tant que paramètre à d'autres fonctions. Par exemple, considérons une fonction qui imprime un nom de fonction : 🎜rrreee🎜printFuncName
prend une fonction et imprime son nom. La fonction runtime.FuncForPC
convertit une adresse de fonction en sa valeur *Func
correspondante, nous permettant d'accéder aux métadonnées de la fonction. 🎜🎜🎜Cas pratique🎜🎜🎜Trier les tranches : 🎜🎜Nous pouvons effectuer un tri basé sur les fonctions des éléments de tranche à l'aide d'adresses de fonction : 🎜rrreee🎜Dans cet exemple, sortByFunc
accepte une tranche et une fonction de comparaison, utilisez ensuite sort.Slice
pour trier les tranches en fonction de la fonction de comparaison. 🎜🎜🎜Assertion de type pointeur de fonction : 🎜🎜L'assertion de type pointeur de fonction nous permet de vérifier si un pointeur de fonction implémente une interface spécifique : 🎜rrreee🎜La fonction isStringer
vérifie si une valeur d'interface donnée implémente Stringer
. Il utilise des assertions de type pour déterminer si la valeur de l'interface pointe vers une fonction qui implémente la méthode String()
. 🎜Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!