Heim  >  Artikel  >  Backend-Entwicklung  >  Ein Artikel vermittelt Ihnen die Grundlagen der Reflexion der Go-Sprachstruktur

Ein Artikel vermittelt Ihnen die Grundlagen der Reflexion der Go-Sprachstruktur

Go语言进阶学习
Go语言进阶学习nach vorne
2023-07-21 10:14:59982Durchsuche

Die Anwendung der Reflexion in Strukturen

Worüber ich letztes Mal gesprochen habe, war nur die Anwendung in gewöhnlichen Variablen. Relativ gesehen gibt es nicht allzu viele Verwendungsszenarien.

Aber die Anwendung von Reflexion in der Struktur wird sich grundsätzlich durch die gesamte Go-Sprachgrundlage ziehen.

Beispielcode

Struktur

type Student struct {
    Name   string   `json:"name" describe:"姓名"`
    Age    int      `json:"age" describe:"年龄"`
    Gender bool     `json:"gender" describe:"性别"`
    Hobby  []string `json:"hobby" describe:"爱好"`
}

main

func main() {
    //实例化结构体
    var s1 = Student{
        Name:   "张三",
        Age:    18,
        Gender: true,
        Hobby:  []string{"吃", "喝", "pia", "玩"},
}
    var t = reflect.TypeOf(s1)
    fmt.Println(t.Name())     //Student
    fmt.Println(t.Kind())     //struct
    fmt.Println(t.NumField()) //结果:4,表示多少个字段
    for i := 0; i < t.NumField(); i++ {
        field := t.Field(i)//每个结构体对象
        /*
            {Name  string json:"name" describe:"姓名" 0 [0] false}
            {Age  int json:"age" describe:"年龄" 16 [1] false}
            {Gender  bool json:"gender" describe:"性别" 24 [2] false}
            {Hobby  []string json:"hobby" describe:"爱好" 32 [3] false}
        */
        //fmt.Println(field)
        fmt.Println("------")
        fmt.Printf("field.Name:%v\n",field.Name)
        fmt.Printf("field.Index:%v\n",field.Index)
        fmt.Printf("field.Type:%v\n",field.Type)
        fmt.Printf("field.Tag:%v\n",field.Tag.Get("describe"))


    }
}

Ausführungsergebnis

Ein Artikel vermittelt Ihnen die Grundlagen der Reflexion der Go-Sprachstruktur

单独反射指定字段信息

main代码

func main() {
    //实例化结构体
    var s1 = Student{
        Name:   "张三",
        Age:    18,
        Gender: true,
        Hobby:  []string{"吃", "喝", "pia", "玩"},
}
    var t = reflect.TypeOf(s1)
    genderField, ok := t.FieldByName("Gender")
    if ok {
        fmt.Println(genderField.Name)                //Gender
        fmt.Println(genderField.Index)               //[2]
        fmt.Println(genderField.Type)                //bool
        fmt.Println(genderField.Tag.Get("describe")) //性别
    }
}

ValueOf

上述的代码只能用的是TypeOf,只能返回类型等信息,相对来说不是太智能,ValueOf可以获取值,同样也能获取类型,相对来说比TypeOf好一点。

示例代码

main

func main() {
    //实例化结构体
    var s1 = Student{
        Name:   "张三",
        Age:    18,
        Gender: true,
        Hobby:  []string{"吃", "喝", "pia", "玩"},
}
    var v = reflect.ValueOf(s1)
    for i := 0; i < v.NumField(); i++ {
        field :=v.Field(i)
        fmt.Println("------")
        fmt.Printf("Kind:%v\n",field.Kind())
        fmt.Printf("值:%v\n",field.Interface())
    }
}

执行结果

Ein Artikel vermittelt Ihnen die Grundlagen der Reflexion der Go-Sprachstruktur


反射方法

上述我们反射的都是值,有没有反射是否可以反射函数,并且调用函数呢??

结构体和绑定函数代码

type Student struct {
    Name   string   `json:"name" describe:"姓名"`
    Age    int      `json:"age" describe:"年龄"`
    Gender bool     `json:"gender" describe:"性别"`
    Hobby  []string `json:"hobby" describe:"爱好"`
}


//无参方法
func (this Student) Say() {
    fmt.Printf("我是%v,我的年龄是%v,我的性别是%v,我的爱好是%v\n", this.Name, this.Age, this.Gender, this.Hobby)
}
//有参数方法
func (this Student) Jump(distance int) {
    fmt.Printf("我是%v,我跳远跳了%v米\n", this.Name, distance)
}

main

func main() {
    //实例化结构体
    var s1 = Student{
        Name:   "张三",
        Age:    18,
        Gender: true,
        Hobby:  []string{"吃", "喝", "pia", "玩"},
}
    var t = reflect.TypeOf(s1)
    var v = reflect.ValueOf(s1)
    fmt.Println(v.NumMethod(),v.NumField())
    for i := 0; i < v.NumMethod(); i++ {
        method := v.Method(i)
        fmt.Println("--------")
        fmt.Println(method)//0x48c4e0 函数地址
        fmt.Println(method.Type())//func(int) 函数类型,形参和返回值
        fmt.Println(t.Method(i).Name)//Jump,函数名,注意,由t来调用的
    }
}

执行结果

Ein Artikel vermittelt Ihnen die Grundlagen der Reflexion der Go-Sprachstruktur


反射调用函数

func main() {
    //实例化结构体
    var s1 = Student{
        Name:   "张三",
        Age:    18,
        Gender: true,
        Hobby:  []string{"吃", "喝", "pia", "玩"},
}
    var v = reflect.ValueOf(s1)


    //通过反射调用函数
    //调用Jump函数
    //反射调用函数必须传一个参数,不管有没有形参都要传
    //var args = []reflect.Value{}
    //v.MethodByName("Say").Call(args)


    //如果需要传参数
    //参数需要用reflect.ValueOf(1) 强转一下


    var args = []reflect.Value{reflect.ValueOf(2)}
    v.MethodByName("Jump").Call(args)
}

注:注意第14行和20行代码区别,如果要传参数,参考第20行代码。

执行结果

Ein Artikel vermittelt Ihnen die Grundlagen der Reflexion der Go-Sprachstruktur


反射注意事项

在平常开发中,尽量慎用反射,原因如下。

  • Die Reflexionsleistung ist möglicherweise relativ gering. Schließlich erfolgt die Bewegung in Vorwärtsrichtung und ist in der Regel ein oder zwei Stufen langsamer als die Vorwärtsbewegung.

  • Je mehr Reflexionen, desto schlechter der Code, TypeOfTypeOfValueOf都有Kind,很多情况是TypeOfValueOf混用的,所以对于基础不好的,极不友好。

  • 在Go中,是没有try und ValueOf

    AllKind

  • , in vielen Fällen

TypeOf<span md-inline="plain"></span>and

ValueOf Es wird gemischt verwendet und ist daher äußerst unfreundlich für Personen mit schlechter Grundierung. In Go gibt es kein versuchen, wenn Reflection die Ausnahme nicht gut verarbeitet, stürzt das Programm direkt ab, möglicherweise an einer unerwarteten Stelle.

  • Zusammenfassung

    🎜🎜🎜 Oben haben wir hauptsächlich über das 🎜🎜🎜 verwandte Wissen 🎜🎜🎜 von Go 🎜🎜🎜 Reflexionsstruktur 🎜🎜 gesprochen 🎜, einschließlich: 🎜🎜🎜🎜🎜🎜🎜Reflexion Anwendung in Struktur🎜🎜🎜
  • Wie man Strukturfeldinformationen individuell widerspiegelt

  • Wert anderer Operationen

  • Wie man Strukturbindungen ausstrahlt. Methoden

Das obige ist der detaillierte Inhalt vonEin Artikel vermittelt Ihnen die Grundlagen der Reflexion der Go-Sprachstruktur. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:Go语言进阶学习. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen