Maison > développement back-end > Golang > le corps du texte

Comment utiliser Reflect.NewAt sur l'interface {} ?

WBOY
Libérer: 2024-02-09 14:00:24
avant
920 Les gens l'ont consulté

Comment utiliser Reflect.NewAt sur linterface {} ?

L'éditeur PHP Xinyi vous présente comment utiliser Reflect.NewAt sur l'interface {}. Reflect.NewAt est une fonction de bibliothèque de réflexion en langage Go, utilisée pour créer une nouvelle instance sur un type d'interface donné. En utilisant réfléchissant.NewAt, nous pouvons créer et initialiser dynamiquement une nouvelle instance d'interface sans spécifier de type spécifique au moment de la compilation. Cela nous donne une plus grande flexibilité et dynamique, permettant au code d'être plus polyvalent et extensible. Ce qui suit vous donnera une explication détaillée de la façon d'utiliser Reflect.NewAt pour créer une instance sur l'interface {}.

Contenu des questions

package main

import (
    "encoding/json"
    "fmt"
    "reflect"
    "unsafe"
)

type Stu struct {
    Name string `json:"name"`
}

func MakeStu() interface{} {
    return Stu{
        Name: "Test",
    }
}

func main() {
    jsonData := []byte(`{"name":"New"}`)
    t1 := MakeStu()
    t2 := MakeStu()
    t3 := MakeStu()

    json.Unmarshal(jsonData, &t1)
    fmt.Println(t1) //Type of t1 becomes map[string]interface{} instead of struct Stu

    newPointer := reflect.New(reflect.ValueOf(t2).Type()).Interface()
    json.Unmarshal(jsonData, newPointer)
    fmt.Println(newPointer) //It works,but it need allocate memory to hold temp new variable

    brokenPointer := reflect.NewAt(reflect.ValueOf(t3).Type(), unsafe.Pointer(&t3)).Interface()
    json.Unmarshal(jsonData, brokenPointer)
    fmt.Println(brokenPointer) // I want to get the pointer of original type based on the existed variable t3,but it crashes.
}
Copier après la connexion

Si je ne connais pas le type spécifique d'interface{} lors du codage, je ne peux pas utiliser interface.(type) pour diffuser. Alors, comment utiliser Reflect.newat sur l'interface {} ?

S'il existe une interface qui contient une méthode qui renvoie interface{}, son type spécifique est struct, mais je ne peux pas déterminer le type de struct lors du codage. Je dois utiliser json.unmarshal pour décoder les données codées par json. Je ne veux pas obtenir map[string]interface{} , je dois donc définir le type du récepteur sur un pointeur vers un type concret d'interface{} . Utiliser Reflect.new est simple, mais consomme de la mémoire supplémentaire, je suis donc curieux de savoir comment utiliser Reflect.newat avec une interface existante{}.

Solution

Je voudrais passer quelques mots pour expliquer le problème.

Fonctions sur lesquelles nous n'avons aucun contrôle makestu() 返回空接口 - 不是具体类型。这将使具体类型对 json.unmarshal() “不可见”,并且 json.unmarshal() 将其视为空接口,而不是具体类型 stu. Nous devons d'une manière ou d'une autre communiquer le type concret au démarécheur.

Je résoudrais ce problème avec un interrupteur de type :

func main() {
    jsondata := []byte(`{"name":"new"}`)
    t1 := makestu()

    switch c := t1.(type) {
    default:
        _ = json.unmarshal(jsondata, &c)
        t1 = c
    }

    fmt.println(t1)
}
Copier après la connexion
Le commutateur

type convertit une interface vide en un type concret et json.unmarshal() la traite comme un type concret. Vous pouvez toujours disposer d'allocations supplémentaires, mais le code est plus lisible et vous ne comptez pas sur la réflexion.

Si je me sentais vraiment aventureux, j'ajouterais une fonction d'assistance qui accepte un pointeur vers une interface nulle, comme ceci :

func unmarshal(data []byte, i *interface{}) (err error) {
    switch c := (*i).(type) {
    default:
        err = json.unmarshal(data, &c)
        *i = c
    }

    return err
}
Copier après la connexion

Cela permettra une utilisation comme celle-ci : 

    jsonData := []byte(`{"name":"New"}`)
    t1 := MakeStu()
    unmarshal(jsonData, &t1)
Copier après la connexion

Cela me semble clair et n'implique pas de réflexion, mais cela n'utilise pas reflect.newat() comme vous l'avez vous-même suggéré. J'espère que mes conseils vous seront toujours utiles.

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!

Étiquettes associées:
source:stackoverflow.com
Déclaration de ce site Web
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!