Go入门23:反射 reflect

Go语言类型

Go语言是静态类型的编程语言,所有数据的类型在编译期确定了。

而且 Go 语言中即使是底层存的是一个类型,声明的类型不一样,也要强制转换才能互用。

例如:

type MyInt int

var i int

var j MyInt

这里的 i 和 j 类型不一致 ,如果需要进行比较或者加减运算 ,需要强制转换类型。

注意:在 Go 语言里面没有隐式转换,遇到不同类型想互用,只能进行强制类型转换。

接口类型变量转换为反射类型对象

import (

    "fmt"

    "reflect"

)

func main() {

    var circle float64 = 6.28

    var icir interface{}

    icir = circle

    fmt.Println("Reflect : circle.Value = ", reflect.ValueOf(icir))

    fmt.Println("Reflect : circle.Type  = ", reflect.TypeOf(icir))

}

上面代码的执行结果如下:

Reflect : circle.Value =  6.28

Reflect : circle.Type  =  float64

可以看到ValueOf和TypeOf的参数都是空接口,因此,这说明可以直接使用变量传进去,比如:

import (

    "fmt"

    "reflect"

)

func main() {

    var circle float64 = 6.28

    fmt.Println("Reflect : circle.Value = ", reflect.ValueOf(circle))    // Reflect : circle.Value = 6.28

    fmt.Println("Reflect : circle.Type  = ", reflect.TypeOf(circle))    // Reflect : circle.Value = float64

}

反射类型对象转换为接口类型变量

这个其实是上面运算的逆过程,简单例子代码如下:

import (

    "fmt"

    "reflect"

)

func main() {

    var circle float64 = 6.28

    var icir interface{}

    icir = circle

    valueref := reflect.ValueOf(icir)

    fmt.Println(valueref)    // 6.28

    fmt.Println(valueref.Interface())    // 6.28

    y := valueref.Interface().(float64)

    fmt.Println(y)    // 6.28

}

用反射进行变量修改

利用反射修改变量时,首先需要使用CanSet函数确认变量是否是可修改的。简单代码示例如下:

import (

    "fmt"

    "reflect"

)

func main() {

    var circle float64 = 6.28

    value := reflect.ValueOf(circle)

    fmt.Println("Reflect : value = ", value)    // 6.28

    fmt.Println("Settability of value : ", value.CanSet())    // false

    value2 := reflect.ValueOf(&circle)

    fmt.Println("Settability of value : ", value2.CanSet())    // false

    value3 := value2.Elem()

    fmt.Println("Settability of value : ", value3.CanSet())    // true

    value3.SetFloat(3.14)

    fmt.Println("Value of value3: ", value3)    // 3.14

    fmt.Println("value of circle: ", circle)    // 3.14

}

性能代价

Go语言反射在带来“方便”的同时,会造成问题:它会带来很大的性能损失。

直接赋值和反射赋值在实际使用中性能差异挺大,所以如果对性能要求较高,那么请谨慎使用反射。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容