📜  GO语言 reflect(1)

📅  最后修改于: 2023-12-03 14:41:37.216000             🧑  作者: Mango

GO语言reflect介绍

GO语言reflect是一种强大的机制,可以在程序运行时检查变量、结构体、接口等,查看其值、类型和属性。这种机制使GO语言比较灵活,可以支持动态类型、泛型、注入等特性。

reflect包

在Go语言中,reflect包提供了检查和操作变量、结构体和接口的功能,应用广泛。reflect包提供了两种重要的类型:Type和Value,分别用于表示变量的类型和值。

Type是指变量实际所属的类型,它包含了类型的名称、方法、字段等信息。Value是指变量的值,它不仅包含了变量的实际值,还包含了变量的类型和属性。

reflect类型

使用reflect.Type可以获取变量的类型信息,包括名称、方法、字段等。

Kind

Kind是reflect.Type的一个方法,返回变量的基础类型,有以下几种可能的值:

  • Bool
  • Int/Int8/Int16/Int32/Int64
  • Uint/Uint8/Uint16/Uint32/Uint64
  • Float32/Float64
  • Complex64/Complex128
  • Array
  • Chan
  • Func
  • Interface
  • Map
  • Ptr
  • Slice
  • String
  • Struct
  • UnsafePointer
Name

Name是reflect.Type的另一个方法,用于获取变量的类型名称。

type Student struct {
    Name string
    Age  int
}
func main() {
    var s Student
    st := reflect.TypeOf(s)
    name := st.Name()
    fmt.Println(name) //Student
}
reflect值

使用reflect.Value可以获取变量的值和属性信息。 和reflect.Type类似,Value也有很多常用的操作方法。

Interface

使用Interface方法可以获取变量的实际值,返回的是一个空接口类型,需要类型断言才能进行实际操作。

func main() {
    var s Student
    st := reflect.ValueOf(s)
    fmt.Println(st.Interface().(Student)) // { 0}
}
Kind

Kind是reflect.Value的一个方法,返回变量的基础类型,用法同reflect.Type。

CanSet

CanSet是reflect.Value的一个方法,用于判断变量是否可修改。

func main() {
    var x float64 = 3.4
    v := reflect.ValueOf(x)
    fmt.Println("settability of v:", v.CanSet()) // false
    p := reflect.ValueOf(&x)
    fmt.Println("settability of p:", p.CanSet()) // true
    v = p.Elem()
    fmt.Println("settability of v:", v.CanSet()) // true
    v.SetFloat(7.1)
    fmt.Println(v.Interface()) //7.1
    fmt.Println(x) //7.1
}
Set

使用Value.Set方法可以修改变量的值,前提是变量可修改。

type Student struct {
    Name string
    Age  int
}
func main() {
    var s Student
    st := reflect.ValueOf(&s).Elem()
    st.FieldByName("Name").SetString("John")
    st.FieldByName("Age").SetInt(18)
    fmt.Println(s) //{John 18}
}
反射应用

reflect机制可以应用于很多场景,比如:

  • JSON序列化和反序列化
  • ORM框架
  • 依赖注入
  • 模板渲染
type Student struct {
    Name string
    Age  int
}
func main() {
    var s Student
    data := `{"Name": "John", "Age": 18}`
    json.Unmarshal([]byte(data), &s)
    fmt.Println(s) //{John 18}
}

以上是GO语言reflect机制的简单介绍,希望对你有帮助。