golang类型断言
niechaoya · · 5070 次点击 · · 开始浏览golang的接口类型是golang的一大神器,下面我们来看看如何将接口类型转换成其他的类型
packagetests
import(
"fmt"
"github.com/go-xorm/core"
"github.com/go-xorm/xorm"
_"github.com/lunny/godbc"
"os"
"testing"
"zks.com/business/module"
)
varDBE*xorm.Engine
funcTest_InitDb(t*testing.T){
dbhost:="localhost\\MSSQLSERVER2008"
dbname:="FoodSafety_KF"
dbuser:="sa"
dbpwd:="sasa"
varerr error
DBE,err=xorm.NewEngine("odbc",fmt.Sprintf("driver=SQLServer;server=%s;database=%s;uid=%s;pwd=%s;",
dbhost,dbname,dbuser,dbpwd))
iferr!=nil{
fmt.Println("failedtoinitializedatabase")
os.Exit(2)
}
DBE.SetMapper(core.SameMapper{})
DBE.ShowDebug=true
DBE.ShowErr=true
DBE.ShowSQL=true
}
funcTest_Something(t*testing.T){
list:=new([]module.Base_Module)
getdata(list)
}
funcgetdata(datainterface{}){
DBE.Limit(3).Find(data)
ifm,ok:=data.(*[]module.Base_Module);ok{
d:=*m
fori:=0;i<len(d);i++{
fmt.Println(d[i].Fullname)
}
}
}
在上面的代码中,我new了一个结构体数组,然后把指向这个结构体数组的指针作为参数发送给了getdata这个函数,而getdata这个函数在接收这个参数时用了interface{}来接收,那么就是说指针被转化成了接口类型。
如果我们去掉m,ok:=data.(*[]module.Base_Module)这句话的话,程序是会报错的。因为接口类型不能取索引,而且也没有Fullname这个字段。
上面那句话的作用就是把接口类型转化成指向[]module.Base_Module的指针,m是接口被转化之后的值,ok是用来标识转换有没有成功。这种转换在golang中就叫做golang的类型断言。
在转换成功后,我又对转换后的值m做了一个取值的操作,这样就可以取到指针指向的地址的值。之后就可以像操作一般结构体数组那样来操作d这个变量了。
如果我们不知道这个data这个参数的类型,但是我们知道要取哪个字段的值,那应该怎么取呢?
答案是:用反射来取,看下面的代码:
funcgetdata(datainterface{}){
DBE.Limit(3).Find(data)
m:=reflect.ValueOf(data).Elem()
fori:=0;i<m.Len();i++{
fmt.Println(m.Index(i).FieldByName("Fullname"))
}
}
把getdataz这个函数改成这样,得到的结果和上面的代码是一样的。对于上面的反射,我们需要注意一点,一定要在reflect.ValueOf(data)后面加上Elem(),不然的话会报错。Elem这个函数的作用就是取得指针指向的地址的值,相当于*操作符。那么如果传过来的参数不是一个指针,而是一个实体,那么就不要用Elem()这个函数了。有疑问加站长微信联系(非本文作者)
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
关注微信- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码` - 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传
收入到我管理的专栏 新建专栏
golang的接口类型是golang的一大神器,下面我们来看看如何将接口类型转换成其他的类型
packagetests
import(
"fmt"
"github.com/go-xorm/core"
"github.com/go-xorm/xorm"
_"github.com/lunny/godbc"
"os"
"testing"
"zks.com/business/module"
)
varDBE*xorm.Engine
funcTest_InitDb(t*testing.T){
dbhost:="localhost\\MSSQLSERVER2008"
dbname:="FoodSafety_KF"
dbuser:="sa"
dbpwd:="sasa"
varerr error
DBE,err=xorm.NewEngine("odbc",fmt.Sprintf("driver=SQLServer;server=%s;database=%s;uid=%s;pwd=%s;",
dbhost,dbname,dbuser,dbpwd))
iferr!=nil{
fmt.Println("failedtoinitializedatabase")
os.Exit(2)
}
DBE.SetMapper(core.SameMapper{})
DBE.ShowDebug=true
DBE.ShowErr=true
DBE.ShowSQL=true
}
funcTest_Something(t*testing.T){
list:=new([]module.Base_Module)
getdata(list)
}
funcgetdata(datainterface{}){
DBE.Limit(3).Find(data)
ifm,ok:=data.(*[]module.Base_Module);ok{
d:=*m
fori:=0;i<len(d);i++{
fmt.Println(d[i].Fullname)
}
}
}
在上面的代码中,我new了一个结构体数组,然后把指向这个结构体数组的指针作为参数发送给了getdata这个函数,而getdata这个函数在接收这个参数时用了interface{}来接收,那么就是说指针被转化成了接口类型。
如果我们去掉m,ok:=data.(*[]module.Base_Module)这句话的话,程序是会报错的。因为接口类型不能取索引,而且也没有Fullname这个字段。
上面那句话的作用就是把接口类型转化成指向[]module.Base_Module的指针,m是接口被转化之后的值,ok是用来标识转换有没有成功。这种转换在golang中就叫做golang的类型断言。
在转换成功后,我又对转换后的值m做了一个取值的操作,这样就可以取到指针指向的地址的值。之后就可以像操作一般结构体数组那样来操作d这个变量了。
如果我们不知道这个data这个参数的类型,但是我们知道要取哪个字段的值,那应该怎么取呢?
答案是:用反射来取,看下面的代码:
funcgetdata(datainterface{}){
DBE.Limit(3).Find(data)
m:=reflect.ValueOf(data).Elem()
fori:=0;i<m.Len();i++{
fmt.Println(m.Index(i).FieldByName("Fullname"))
}
}
把getdataz这个函数改成这样,得到的结果和上面的代码是一样的。对于上面的反射,我们需要注意一点,一定要在reflect.ValueOf(data)后面加上Elem(),不然的话会报错。Elem这个函数的作用就是取得指针指向的地址的值,相当于*操作符。那么如果传过来的参数不是一个指针,而是一个实体,那么就不要用Elem()这个函数了。