Maison >développement back-end >Golang >Comment puis-je accéder aux champs privés dans Go à des fins de test et à d'autres fins légitimes ?

Comment puis-je accéder aux champs privés dans Go à des fins de test et à d'autres fins légitimes ?

Linda Hamilton
Linda Hamiltonoriginal
2024-12-19 09:36:10983parcourir

How Can I Access Private Fields in Go for Testing and Other Legitimate Purposes?

Accès aux champs privés dans Go : solutions pour les packages amis et les tests en boîte blanche

Dans Go, les champs de structure sont généralement privés par défaut, les protégeant de l’accès par des packages externes. Cependant, il peut y avoir des scénarios dans lesquels vous devez accéder à des champs privés à partir d'un autre package pour des tests en boîte blanche ou pour d'autres raisons légitimes.

Méthode 1 : utilisation de Reflection (versions Go antérieures à 1.7)

Avant Go 1.7, le package Reflect fournissait un moyen d'accéder et de modifier les champs non exportés à l'aide de la réflexion. Le code suivant montre comment modifier les champs privés à l'aide de la réflexion :

func read_foo(f *Foo) {
    v := reflect.ValueOf(*f)
    y := v.FieldByName("y")
    fmt.Println(y.Interface())
}

Cependant, la modification des champs non exportés à l'aide de la réflexion déclenchera une panique dans les versions Go 1.7 et ultérieures.

Méthode 2 : Manipulation du pointeur (Go versions 1.7 et ultérieures)

Dans Go 1.7 et ultérieures, le package Reflect a été mis à jour pour interdire la modification des champs non exportés à partir d'autres packages. Cependant, il existe une approche risquée qui implique la manipulation du pointeur à l'aide du package unsafe :

func change_foo(f *Foo) {
    ptrTof := unsafe.Pointer(f)
    ptrTof = unsafe.Pointer(uintptr(ptrTof) + uintptr(8))
    ptrToy := (**Foo)(ptrTof)
    *ptrToy = nil
}

Attention : L'utilisation d'unsafe à cette fin est fortement déconseillée. Il n'est pas portable, peut s'interrompre en cas de modifications des structures de données et interférer avec le garbage collection.

Tests en boîte blanche

Pour les tests en boîte blanche, où vous avez besoin d'accéder aux champs privés d'un package, vous pouvez utiliser la convention de dénomination _test.go. Tous les fichiers avec _test.go à la fin seront compilés uniquement lors de l'exécution des tests. Cela vous permet d'accéder aux champs privés pour les tests en boîte blanche tout en les gardant privés pour le code de production.

// mypackage/foo_test.go
package mypackage

import (
    "testing"
)

func TestFoo(t *testing.T) {
    f := new(Foo)
    // Access and modify private fields within Foo
}

Conclusion

L'accès aux champs privés à partir d'un autre package devrait être fait avec prudence et pour des raisons légitimes uniquement. Bien que des méthodes telles que la réflexion ou la manipulation dangereuse du pointeur puissent fournir des solutions de contournement, elles comportent des risques et des inconvénients importants. Pour les tests en boîte blanche, la convention de dénomination _test.go offre une approche plus sûre et plus pratique pour accéder aux champs privés au sein d'un package.

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn