go - 如何检查接口是否是指向切片的指针
问题描述
我知道如何检查接口是否是指针:
func isPointerArray(i interface{}) bool {
if i == nil {
return false
}
if reflect.ValueOf(i).Kind() != reflect.Ptr {
return false
}
}
但是如何检查该指针是否为切片?TypeOf
是一个指针。
解决方案
如果 value 的 kind 是reflect.Ptr
,你可以Value.Elem()
用来获取指向的值,你可以将它的 kind 与 进行比较reflect.Slice
。
这就是它的样子:
func isPtrSlice(i interface{}) bool {
if i == nil {
return false
}
v := reflect.ValueOf(i)
if v.Kind() != reflect.Ptr {
return false
}
return v.Elem().Kind() == reflect.Slice
}
但是有一个问题。如果传递的值是指向切片类型的指针,但值本身是nil
指针,则会报告false
. 可以理解,因为没有类型可以是切片的指向值。这可能是也可能不是您想要的。
如果您true
甚至想要nil
指针值(指向切片类型的指针),您可以使用reflect.Type
而不是reflect.Value
. 这也适用于nil
指针,因为即使没有指向的值,仍然有一个指向的类型(称为基本类型)。
func isPtrSlice2(i interface{}) bool {
if i == nil {
return false
}
t := reflect.TypeOf(i)
if t.Kind() != reflect.Ptr {
return false
}
return t.Elem().Kind() == reflect.Slice
}
测试上述功能:
vals := []interface{}{
nil,
"a",
&image.Point{},
[]string{},
&[]string{},
(*[]string)(nil),
}
for _, v := range vals {
fmt.Printf("%-14T isPtrSlice: %-5t, isPtrSlice2: %t\n",
v, isPtrSlice(v), isPtrSlice2(v))
}
哪个会输出(在Go Playground上试试):
<nil> isPtrSlice: false, isPtrSlice2: false
string isPtrSlice: false, isPtrSlice2: false
*image.Point isPtrSlice: false, isPtrSlice2: false
[]string isPtrSlice: false, isPtrSlice2: false
*[]string isPtrSlice: true , isPtrSlice2: true
*[]string isPtrSlice: false, isPtrSlice2: true
正如您在最后一行(其中值是nil
type 的指针*[]string
)中看到的那样,在isPtrSlice()
返回false
时isPtrSlice2()
返回true
。
推荐阅读
- gremlin - gremlin shortestPath() with (ShortestPath.edges, Direction.OUT)
- android - 如何以编程方式在android中创建透明活动?
- database - 如果我启用 HR 用户和 XEPDBA1 数据库,我在 oracle 18c 中与根数据库建立的连接会停止工作吗?
- python - 使用循环在 seaborn 直方图子图中添加分位数和平均线
- python - 如何删除“一对多”关系的孩子?(SQL炼金术)
- distributed-system - 在 Orleans Grain 中调用外部服务 (Rest api)/数据库 CRUD 操作
- javascript - 在同步函数中从 AWS Lambda 发出 AWS CloudWatch 指标
- python - Pyqt5 qtablewidget 检测单元格何时更改
- android - 无法正确处理房间迁移
- firebase - Firebase onCall 函数可以执行重试吗?