使用interface接口进行处理时,由于需要对传入的参数进行断言,这就涉及到反射(reflect)的使用。
废话不多说,直接上代码
由于使用的是go test对例子进行测试,因此可以分为以下几个步骤
1、创建client_test.go
文件
type ss struct {
index int
value string
}
func TestFun(t *testing.T) {
var sss = ss{index: 1, value: "data"}
dd(sss)
}
func dd(v ...interface{}) {
for _, value := range v {
switch value.(type) {
case int:
fmt.Println("int")
break
case string:
fmt.Println("string")
break
case ss:
fmt.Println("ss")
var ds = reflect.ValueOf(value)
fmt.Println(ds.FieldByName("value"))
break
}
}
}
2、执行命令:
go test -v client_test.go
输出的结果为:
=== RUN TestFun
ss
data
--- PASS: TestFun (0.00s)
PASS
ok command-line-arguments 0.001s
可见在输入的类型为结构体类型时,执行的是type的第三个类型,即case:ss
,由于传入的是结构体,
需要使用断言中的结构体相关函数来进行取值,反射中相关结构体的几个函数如下:
##########结构体相关: func (v Value) NumField() int // 获取结构体字段(成员)数量func (v Value) Field(i int) reflect.Value //根据索引获取结构体字段
func (v Value) FieldByIndex(index []int) reflect.Value //
根据索引链获取结构体嵌套字段func (v Value) FieldByName(string) reflect.Value //
根据名称获取结构体的字段,不存在返回reflect.ValueOf(nil)func (v Value) FieldByNameFunc(match func(string) bool) Value //
根据匹配函数 match 获取字段,如果没有匹配的字段,则返回零值(reflect.ValueOf(nil))########通道相关: func (v Value) Send(x reflect.Value)// 发送数据(会阻塞),v 值必须是可写通道。
func (v Value) Recv() (x reflect.Value, ok bool) // 接收数据(会阻塞),v
值必须是可读通道。func (v Value) TrySend(x reflect.Value) bool // 尝试发送数据(不会阻塞),v
值必须是可写通道。func (v Value) TryRecv() (x reflect.Value, ok bool) // 尝试接收数据(不会阻塞),v
值必须是可读通道。func (v Value) Close() // 关闭通道
########函数相关 func (v Value) Call(in []Value) (r []Value) // 通过参数列表 in 调用 v 值所代表的函数(或方法)。函数的返回值存入 r 中返回。 // 要传入多少参数就在 in 中存入多少元素。 // Call
即可以调用定参函数(参数数量固定),也可以调用变参函数(参数数量可变)。func (v Value) CallSlice(in []Value) []Value // 调用变参函数