[go 反射] 进阶
本文你将了解
- 反射拷贝指针
- 通过反射创建对象
- 将panic风险尽可能降低
反射拷贝指针 秘诀在于将任何指针都想象成一个普通的uint64整数类型
go
import (
"fmt"
"reflect"
)
func main(){
var one,two *int=new(int),nil
*one=23
//现在要将one的指针拷贝给two,让它们指向相同的内存
tvl:=reflect.ValueOf(&two).Elem()
ovl:=reflect.ValueOf(one)
if tvl.CanSet(){
tvl.Set(ovl)
*two=26
fmt.Println(*one,*two)//两者都是26
}
}
反射创建对象 有时候对于未定义的指针想给它new个对象,这时候咋们的反射创建就来了
go
import(
"fmt"
"reflect"
)
func main(){
var one *int =nil
ovl:=reflect.ValueOf(&one).Elem()
if ovl.IsNil(){
fmt.Println("is nil. create new object")
if ovl.CanSet(){
ovl.Set(reflect.New(reflect.TypeOf(one).Elem()))//注意type后面一定elem,因为type出来是*in,我们这里要new的是int,参数更不能传*one,因为one此时就是个空指针
*one=23
fmt.Println(*one)
}
}
}
panic风险尽可能将到最低
大多数我们用到反射以主流为参数的场景可能是这样的func(any,any)error
.所以为了避免未知的意外panic,做到每一步都知道你在做什么
go
func totest(src any)(err error){
stp:=reflect.TypeOf(src)
switch stp.Kind(){//列出来哪些类型做哪些特殊处理,只处理预料之类的
case reflect.Pointer:
//pointer类型就可能出现空指针的情况,进行空指针判断
case reflect.Struct:
case reflect.Int:
default:
err=errors.New("don't support kind "+stp.Kind().String())
}
return
}