美文网首页走进迈莫
面试官问我go反射 我怀疑他要给我60k

面试官问我go反射 我怀疑他要给我60k

作者: 迈莫coding | 来源:发表于2021-01-26 12:10 被阅读0次

    目录

    • isNil()/isValid()
    • 反射创建对象
    • Call()函数
    • 闲聊
    • 【迈莫coding】

    go发射第一弹【typeOf使用】
    链接:https://mp.weixin.qq.com/s/F8yZyqC5UwoewsX0THqy1w

    go反射第二弹【valuef使用】
    链接:https://mp.weixin.qq.com/s/lgZykTL8ls6aG0OMNSbZMw

    isNil()/isValid()

    go语言中,通过 reflect.ValueOf() 方法获取 reflect.Value 对象时,在reflect.Value 对象中提供了一些方法用来判断值是否为空,如下表所示:

    示例

    package main
    import (
       "fmt"
       "reflect"
    )
    type User struct{
       Name string
       Age int
    }
    func main(){
       user := &User{
          Name : "迈莫coding",
       }
       values := reflect.ValueOf(user)
       fmt.Println("user对象是否为空:", values.IsNil())
       values = values.Elem()
       fmt.Println("Name字段属性是否存在:",           values.FieldByName("Name").IsValid())
    }
    

    结果:

    user对象是否为空: false
    Name字段属性是否存在: true
    

    代码说明:

    - 第11行:实例化User对象
    - 第15行:判断反射对象values是否为空
    - 第17行:判断反射对象中"Name"字段属性是否有效
    

    反射创建对象

    在go语言中,若已知 reflect.Type 类型时,可以通过 reflect.New() 方法进行反射创建实例,但参数注意的是,只能传入 reflect.Type 类型对象。

    示例

    package main
    
    import (
      "fmt"
      "reflect"
    )
    
    type User struct{
       Name string
    }
    func main() {
       types := reflect.TypeOf(&User{})
       values := reflect.New(types)
    fmt.Println("反射创建出对象的类型和种类:", values.Type(), values.Kind())
    }
    

    结果

    反射创建出对象的类型和种类: **main.User ptr
    

    Call()函数

    如果反射值对象(reflect.Value)中值的类型为函数时,可以通过 reflect.Value 调用该函数。使用反射调用函数时,需要将参数使用反射值对象的切片 []reflect.Value 构造后传入 Call() 方法中,调用完成时,函数的返回值通过 []reflect.Value 返回。

    示例

    package main
    
    import (
      "fmt"
      "import"
    )
    
    func add(x, y int) int {
      return x + y 
    }
    
    func main() {
      addValue := reflect.ValueOf(add)
       // 构造函数参数, 传入两个整型值
        paramList := []reflect.Value{reflect.ValueOf(10),   reflect.ValueOf(20)}
        // 反射调用函数
        retList := funcValue.Call(paramList)
        // 获取第一个返回值, 取整数值
        fmt.Println(retList[0].Int())
    }
    

    代码说明如下:

    第 9~12 行:定义一个普通的加法函数。
    第 17 行:将 add 函数包装为反射值对象。
    第 20 行:将 10 和 20 两个整型值使用 reflect.ValueOf 包装为 reflect.Value,再将反射值对象的切片 []reflect.Value 作为函数的参数。
    第 23 行:使用 funcValue 函数值对象的 Call() 方法,传入参数列表 paramList 调用 add() 函数。
    第 26 行:调用成功后,通过 retList[0] 取返回值的第一个参数,使用 Int 取返回值的整数值。
    

    提示

    反射调用函数的过程需要构造大量的 reflect.Value 和中间变量,对函数参数值进行逐一检查,还需要将调用参数复制到调用函数的参数内存中。调用完毕后,还需要将返回值转换为 reflect.Value,用户还需要从中取出调用值。因此,反射调用函数的性能问题尤为突出,不建议大量使用反射函数调用。

    闲聊

    • 读完文章,自己是不是和反射的cp率又提高了
    • 我是迈莫,欢迎大家和我交流

    文章也会持续更新,可以微信搜索「 迈莫coding 」第一时间阅读。

    相关文章

      网友评论

        本文标题:面试官问我go反射 我怀疑他要给我60k

        本文链接:https://www.haomeiwen.com/subject/pldgzktx.html