Go语言反射深入讲解

反射基础概念什么是反射?反射是一种在运行时检查和操作类型的机制。它允许程序动态地获取类型信息,并对对象进行操作。基本类型反射的基本类型包括:reflect.Type:表示类型信息。reflect.Value:表示值信息。获取类型信息使用reflect.TypeOfpackag

反射基础概念

什么是反射? 反射是一种在运行时检查和操作类型的机制。它允许程序动态地获取类型信息,并对对象进行操作。

基本类型 反射的基本类型包括:

  • reflect.Type:表示类型信息。
  • reflect.Value:表示值信息。

获取类型信息

使用 reflect.TypeOf

package main

import (
    "fmt"
    "reflect"
)

func main() {
    var a int = 10
    t := reflect.TypeOf(a)
    fmt.Println(t) // 输出:int
}

使用 reflect.ValueOf

package main

import (
    "fmt"
    "reflect"
)

func main() {
    var a int = 10
    v := reflect.ValueOf(a)
    fmt.Println(v) // 输出:10
}

类型转换

使用 Interface 方法

package main

import (
    "fmt"
    "reflect"
)

func main() {
    var a int = 10
    v := reflect.ValueOf(a)
    b := v.Interface().(int)
    fmt.Println(b) // 输出:10
}

使用 Convert 方法

package main

import (
    "fmt"
    "reflect"
)

func main() {
    var a int = 10
    v := reflect.ValueOf(a)
    b := v.Convert(reflect.TypeOf(float64(0))).Interface().(float64)
    fmt.Println(b) // 输出:10
}

检查类型

使用 Kind 方法

package main

import (
    "fmt"
    "reflect"
)

func main() {
    var a int = 10
    t := reflect.TypeOf(a)
    fmt.Println(t.Kind()) // 输出:int
}

使用 Type 方法

package main

import (
    "fmt"
    "reflect"
)

type Person struct {
    Name string
    Age  int
}

func main() {
    p := Person{"Alice", 25}
    t := reflect.TypeOf(p)
    fmt.Println(t) // 输出:main.Person
}

操作结构体

获取结构体字段

package main

import (
    "fmt"
    "reflect"
)

type Person struct {
    Name string
    Age  int
}

func main() {
    p := Person{"Alice", 25}
    v := reflect.ValueOf(p)
    t := v.Type()

    for i := 0; i < v.NumField(); i++ {
        field := t.Field(i)
        value := v.Field(i)
        fmt.Printf("%s: %v\n", field.Name, value.Interface())
    }
}

修改结构体字段

package main

import (
    "fmt"
    "reflect"
)

type Person struct {
    Name string
    Age  int
}

func main() {
    p := Person{"Alice", 25}
    v := reflect.ValueOf(&p).Elem()
    t := v.Type()

    for i := 0; i < v.NumField(); i++ {
        field := t.Field(i)
        value := v.Field(i)
        switch field.Name {
        case "Name":
            value.SetString("Bob")
        case "Age":
            value.SetInt(30)
        }
    }

    fmt.Println(p) // 输出:{Bob 30}
}

操作数组和切片

获取数组和切片长度

package main

import (
    "fmt"
    "reflect"
)

func main() {
    a := []int{1, 2, 3, 4, 5}
    v := reflect.ValueOf(a)
    fmt.Println(v.Len()) // 输出:5
}

遍历数组和切片

package main

import (
    "fmt"
    "reflect"
)

func main() {
    a := []int{1, 2, 3, 4, 5}
    v := reflect.ValueOf(a)

    for i := 0; i < v.Len(); i++ {
        fmt.Println(v.Index(i).Interface())
    }
}

操作映射表

获取映射表键值

package main

import (
    "fmt"
    "reflect"
)

func main() {
    m := map[string]int{"a": 1, "b": 2, "c": 3}
    v := reflect.ValueOf(m)

    for _, key := range v.MapKeys() {
        value := v.MapIndex(key)
        fmt.Printf("%v: %v\n", key.Interface(), value.Interface())
    }
}

修改映射表

package main

import (
    "fmt"
    "reflect"
)

func main() {
    m := map[string]int{"a": 1, "b": 2, "c": 3}
    v := reflect.ValueOf(&m).Elem()

    v.SetMapIndex(reflect.ValueOf("d"), reflect.ValueOf(4))

    fmt.Println(m) // 输出:map[a:1 b:2 c:3 d:4]
}

操作接口

获取接口值

package main

import (
    "fmt"
    "reflect"
)

func main() {
    var i interface{} = "Hello, World!"
    v := reflect.ValueOf(i)
    fmt.Println(v.Interface()) // 输出:Hello, World!
}

修改接口值

package main

import (
    "fmt"
    "reflect"
)

func main() {
    var i interface{} = "Hello, World!"
    v := reflect.ValueOf(&i).Elem()
    v.Set(reflect.ValueOf("Goodbye, World!"))

    fmt.Println(i) // 输出:Goodbye, World!
}

操作函数

调用函数

package main

import (
    "fmt"
    "reflect"
)

func add(a, b int) int {
    return a + b
}

func main() {
    args := []reflect.Value{reflect.ValueOf(1), reflect.ValueOf(2)}
    result := reflect.ValueOf(add).Call(args)[0].Interface().(int)
    fmt.Println(result) // 输出:3
}

调用方法

package main

import (
    "fmt"
    "reflect"
)

type Person struct {
    Name string
    Age  int
}

func (p *Person) SayHello() string {
    return fmt.Sprintf("%s says hello!", p.Name)
}

func main() {
    p := &Person{"Alice", 25}
    method := reflect.ValueOf(p).MethodByName("SayHello")
    result := method.Call(nil)[0].Interface().(string)
    fmt.Println(result) // 输出:Alice says hello!
}

反射与类型断言

类型断言

package main

import (
    "fmt"
    "reflect"
)

func main() {
    var i interface{} = "Hello, World!"
    if str, ok := i.(string); ok {
        fmt.Println(str) // 输出:Hello, World!
    } else {
        fmt.Println("Not a string")
    }
}

使用反射进行类型断言

package main

import (
    "fmt"
    "reflect"
)

func main() {
    var i interface{} = "Hello, World!"
    v := reflect.ValueOf(i)
    if v.Kind() == reflect.String {
        fmt.Println(v.Interface()) // 输出:Hello, World!
    } else {
        fmt.Println("Not a string")
    }
}

反射与类型转换

类型转换

package main

import (
    "fmt"
    "reflect"
)

func main() {
    var i interface{} = 10
    v := reflect.ValueOf(i)
    f := v.Convert(reflect.TypeOf(float64(0))).Interface().(float64)
    fmt.Println(f) // 输出:10
}

复杂类型的转换

package main

import (
    "fmt"
    "reflect"
)

type Point struct {
    X float64
    Y float64
}

func main() {
    var p interface{} = Point{X: 1.0, Y: 2.0}
    v := reflect.ValueOf(p)
    newPoint := v.Convert(reflect.TypeOf(Point{})).Interface().(Point)
    fmt.Println(newPoint) // 输出:{1 2}
}
点赞 0
收藏 1
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
天涯学馆
天涯学馆
0x9d6d...50d5
资深大厂程序员,12年开发经验,致力于探索前沿技术!