Heim > Backend-Entwicklung > Golang > Bestimmen Sie, ob das Schnittstellentypfeld der Struktur festgelegt ist

Bestimmen Sie, ob das Schnittstellentypfeld der Struktur festgelegt ist

PHPz
Freigeben: 2024-02-09 18:27:08
nach vorne
693 Leute haben es durchsucht

Bestimmen Sie, ob das Schnittstellentypfeld der Struktur festgelegt ist

Der PHP-Editor Xiaoxin ist hier, um einen Trick zu verraten, mit dem Sie feststellen können, ob das Schnittstellentypfeld von struct festgelegt ist. In der Go-Sprache kann der Strukturtyp mehrere Schnittstellen implementieren. Indem wir feststellen, ob das Feld „Schnittstellentyp“ festgelegt ist, können wir leicht feststellen, ob eine Struktur eine bestimmte Schnittstelle implementiert. Diese Technik ist sehr praktisch. Sie kann den Objekttyp im Code genau bestimmen und entsprechend behandeln. Schauen wir uns als Nächstes die spezifische Implementierungsmethode an!

Frageninhalt

Gegeben sei eine Struktur, deren Felder zum Schnittstellentyp gehören:

type a interface { foo() }
type b interface { bar() }

type container struct {
   fielda a
   fieldb b
   ...
}
Nach dem Login kopieren

Und die Strukturen, die diese Schnittstellen implementieren:

type a struct {}
func (*a) foo() {}
func newa() *a { return &a{} }

type b struct {}
func (*b) bar() {}
func newb() *b { return &b{} }
Nach dem Login kopieren

Und der Code, der die container-Instanz erstellt, ohne explizit alle Felder festzulegen:

c := &container{}
c.fielda = newa()
// c.fieldb = newb()  // <-- fieldb not explicitly set
Nach dem Login kopieren

Wie kann ich mithilfe von Reflektion ein Feld erkennen, das nicht explizit festgelegt ist?

Überprüfen Sie den Wert von fieldb zur Laufzeit, vscode meldet den Wert gerne als nil. Ebenso kommt es beim Versuch, c.fieldb.bar() aufzurufen, aufgrund einer Null-Zeiger-Dereferenzierung zu einer Panik. Aber durch Reflexion können Sie isnil nicht testen, noch gibt iszero true zurück:

func validateContainer(c *container) {
    tC := reflect.TypeOf(*c)
    for i := 0; i < tC.NumField(); i++ {
        reflect.ValueOf(tC.Field(i)).IsNil() // panics
        reflect.ValueOf(tC.Field(i)).IsZero() // always false
        reflect.ValueOf(tC.Field(i)).IsValid() // always true
    }
}
Nach dem Login kopieren

Lösung

Sie sollten nachsehen reflect.valueof(*c) 的字段,而不是 reflect.typeof(*c).

package main

import (
    "fmt"
    "reflect"
)

func validatecontainer(c *container) {
    tc := reflect.typeof(*c)
    vc := reflect.valueof(*c)
    for i := 0; i < vc.numfield(); i++ {
        if f := vc.field(i); f.kind() == reflect.interface {
            fmt.printf("%v: isnil: %v, iszero: %v, isvalid: %v\n",
                tc.field(i).name,
                f.isnil(),
                f.iszero(),
                f.isvalid(),
            )
        }
    }

    // tc.field(i) returns a reflect.structfield that describes the field.
    // it's not the field itself.
    fmt.printf("%#v\n", reflect.valueof(tc.field(0)))
}

type a interface{ foo() }
type b interface{ bar() }

type container struct {
    fielda a
    fieldb b
}

type a struct{}

func (*a) foo() {}
func newa() *a  { return &a{} }

func main() {
    c := &container{}
    c.fielda = newa()
    validatecontainer(c)
}
Nach dem Login kopieren

Ausgabe:

FieldA: IsNil: false, isZero: false, IsValid: true
FieldB: IsNil: true, isZero: true, IsValid: true
reflect.StructField{Name:"FieldA", PkgPath:"", Type:(*reflect.rtype)(0x48de20), Tag:"", Offset:0x0, Index:[]int{0}, Anonymous:false}
Nach dem Login kopieren

Das obige ist der detaillierte Inhalt vonBestimmen Sie, ob das Schnittstellentypfeld der Struktur festgelegt ist. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:stackoverflow.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage