Go语言反射操作

幸运草 2020年4月18日22:58:04前端框架评论阅读模式

反射操作常用函数和方法

func (v Value) Elem() Value

Elem返回v持有的接口保管的值的Value封装,或者v持有的指针指向的值的Value封装。如果v的Kind不是Interface或Ptr会panic;如果v持有的值为nil,会返回Value零值。

func (v Value) SetInt(x int64)

设置v的持有值。如果v的Kind不是Int、Int8、Int16、Int32、Int64之一或者v.CanSet()返回假,会panic。

func (v Value) Int() int64

返回v持有的有符号整数(表示为int64),如果v的Kind不是Int、Int8、Int16、Int32、Int64会panic

func (v Value) Kind() Kind

Kind返回v持有的值的分类,如果v是Value零值,返回值为Invalid

func (v Value) NumField() int

返回v持有的结构体类型值的字段数,如果v的Kind不是Struct会panic

func (v Value) Field(i int) Value

返回结构体的第i个字段(的Value封装)。如果v的Kind不是Struct或i出界会panic

func (v Value) SetString(x string)

设置v的持有值。如果v的Kind不是String或者v.CanSet()返回假,会panic。

func (v Value) NumMethod() int

返回v持有值的方法集的方法数目。

func (v Value) MethodByName(name string) Value

返回v的名为name的方法的已绑定(到v的持有值的)状态的函数形式的Value封装。返回值调用Call方法时不应包含接收者;返回值持有的函数总是使用v的持有者作为接收者(即第一个参数)。如果未找到该方法,会返回一个Value零值。

func (v Value) Call(in []Value) []Value

Call方法使用输入的参数in调用v持有的函数。例如,如果len(in) == 3,v.Call(in)代表调用v(in[0], in[1], in[2])(其中Value值表示其持有值)。如果v的Kind不是Func会panic。它返回函数所有输出结果的Value封装的切片。和go代码一样,每一个输入实参的持有值都必须可以直接赋值给函数对应输入参数的类型。如果v持有值是可变参数函数,Call方法会自行创建一个代表可变参数的切片,将对应可变参数的值都拷贝到里面。

func (v Value) Type() Type

返回v持有的值的类型的Type表示。

反射操作应用

一、通过反射操作基本类型,来改变基本类型的值。

package main

import (
    "fmt"
    "reflect"
)

func main() {
    var a int = 1
    a = 100
    val := reflect.ValueOf(&a)
    val.Elem().SetInt(200)
    b := val.Elem().Int()
    fmt.Printf("a => %d , b => %dn", a, b)
}

运行结果:

a => 200 , b => 200

二、反射操作结构体及调用结构体方法。

package main

import (
    "fmt"
    "reflect"
)

type School struct {
    Name   string
    Course string
}

func (s School) Echo() {
    fmt.Printf("name : %s , Course : %s n", s.Name, s.Course)
}

func main() {
    o := School{
        Name:   "oldboy",
        Course: "Linux",
    }

    val := reflect.ValueOf(&o)
    kd := val.Kind()

    if kd != reflect.Ptr && val.Elem().Kind() == reflect.Struct {
        fmt.Println("expect struct")
        return
    }
    //获取字段数量
    fields := val.Elem().NumField()
    fmt.Printf("struct has %d fieldn", fields)
    //获取字段的类型
    for i := 0; i < fields; i++ {
        fmt.Printf("%d %vn", i, val.Elem().Field(i).Kind())
    }
    // 操作结构体
    val.Elem().Field(1).SetString("Golang")

    //获取方法数量
    methods := val.NumMethod()
    fmt.Printf("struct has %d methodsn", methods)

    //反射调用的Echo方法
    var params []reflect.Value
    val.Elem().Method(0).Call(params)
}

运行结果:

struct has 2 field
0 string
1 string
struct has 1 methods
name : oldboy , Course : Golang

反射综合应用

1、定义一个结构体
2、给结构体赋值
3、用反射获取结构体的下标、结构体名称、类型、值
4、改变结构体的值

package main

import (
    "fmt"
    "reflect"
)

type Student struct {
    Name string
    Age  int
}

func main() {
    u := Student{"oldboy", 18}
    v := reflect.ValueOf(&u).Elem()
    t := v.Type()
    for i := 0; i < v.NumField(); i++ {
        f := v.Field(i)
        fmt.Printf("构体的下标: %d: 名称: %s 类型: %s 值: %vn", i,
            t.Field(i).Name, f.Type(), f.Interface())
    }
    v.Field(0).SetString("老男孩")
    v.Field(1).SetInt(100)
    fmt.Println("u is now", u)
}

特别声明:以上文章内容仅代表作者本人观点,不代表变化吧观点或立场。如有关于作品内容、版权或其它问题请于作品发表后的30日内与变化吧联系。

  • 赞助本站
  • 微信扫一扫
  • weinxin
  • 加入Q群
  • QQ扫一扫
  • weinxin
幸运草
Go语言接口规则 前端框架

Go语言接口规则

Go语言接口规则 接口是一个或多个方法签名的集合。任何类型的方法集中只要拥有该接口对应的全部方法签名。就表示它 "实现" 了该接口,无须在该类型上显式声明实现了哪个接口。对应方法,是指有相同名称、参数...
Go语言中处理 HTTP 服务器 前端框架

Go语言中处理 HTTP 服务器

1 概述 包 net/http 提供了HTTP服务器端和客户端的实现。本文说明关于服务器端的部分。 快速开始: package main import (   "log"   "net/http" )...

发表评论