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语言反射在带来“方便”的同时,会造成问题:它会带来很大的性能损失。
直接赋值和反射赋值在实际使用中性能差异挺大,所以如果对性能要求较高,那么请谨慎使用反射。