>백엔드 개발 >Golang >Go 언어 구조 반영의 기본을 가르치는 기사

Go 언어 구조 반영의 기본을 가르치는 기사

Go语言进阶学习
Go语言进阶学习앞으로
2023-07-21 10:14:591040검색

구조에서의 반사 적용

지난 시간에 말씀드린 것은 단지 일반 변수에서의 적용에 관한 것이었습니다. 상대적으로 사용 시나리오는 그리 많지 않습니다.

그러나 구조의 반영 적용은 기본적으로 전체 Go 언어 기반을 통해 실행됩니다.

예제 코드

구조

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"))


    }
}

실행 결과

Go 언어 구조 반영의 기본을 가르치는 기사

单独反射指定字段信息

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())
    }
}

执行结果

Go 언어 구조 반영의 기본을 가르치는 기사


反射方法

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

结构体和绑定函数代码

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来调用的
    }
}

执行结果

Go 언어 구조 반영의 기본을 가르치는 기사


反射调用函数

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行代码。

执行结果

Go 언어 구조 반영의 기본을 가르치는 기사


反射注意事项

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

  • 반사 성능은 상대적으로 낮을 수 있습니다. 결국 정방향으로 이동하며 일반적으로 정방향 작동보다 한두 단계 느립니다.

  • 반사가 많을수록 코드는 더 나빠집니다. TypeOfTypeOfValueOf都有Kind,很多情况是TypeOfValueOf混用的,所以对于基础不好的,极不友好。

  • 在Go中,是没有try ValueOf

    All종류

  • , 많은 경우

유형<span md-inline="plain"></span>and

혼합해서 사용하기 때문에 기초가 약한 분들에게는 굉장히 불친절합니다. Go에는 try, 리플렉션이 예외를 잘 처리하지 못하면 프로그램이 예상치 못한 곳에서 직접 충돌하게 됩니다.

  • 요약

    🎜🎜🎜 위에서 우리는 주로 Go 🎜🎜🎜 반사 구조 🎜🎜🎜의 🎜🎜🎜 관련 지식 🎜🎜🎜에 대해 이야기했습니다. , 포함: 🎜🎜🎜🎜🎜🎜🎜반사 구조에 적용🎜🎜🎜
  • 구조체 필드 정보를 개별적으로 반영하는 방법

  • 다른 연산의 값

  • 구조체 바인딩 방법을 방사하는 방법

위 내용은 Go 언어 구조 반영의 기본을 가르치는 기사의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 Go语言进阶学习에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제