如何检查接口是否是指向切片的指针
How to check if interface is a a pointer to a slice
我知道如何检查接口是否为指针:
func isPointerArray(i interface{}) bool {
if i == nil {
return false
}
if reflect.ValueOf(i).Kind() != reflect.Ptr {
return false
}
}
但是我如何检查该指针是否是一个切片? TypeOf
是一个指针。
您可以使用 type assertions:
package main
import "fmt"
func main() {
var value interface{}
value = &[]int{1, 2}
if res, ok := value.(*[]int); ok {
fmt.Println(res)
}
}
如果值的种类是reflect.Ptr
,你可以用Value.Elem()
得到指向的值,你可以将它的种类与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
正如您在最后一行中看到的(其中值是 *[]string
类型的 nil
指针) isPtrSlice()
returns false
while isPtrSlice2()
returns true
.
我知道如何检查接口是否为指针:
func isPointerArray(i interface{}) bool {
if i == nil {
return false
}
if reflect.ValueOf(i).Kind() != reflect.Ptr {
return false
}
}
但是我如何检查该指针是否是一个切片? TypeOf
是一个指针。
您可以使用 type assertions:
package main
import "fmt"
func main() {
var value interface{}
value = &[]int{1, 2}
if res, ok := value.(*[]int); ok {
fmt.Println(res)
}
}
如果值的种类是reflect.Ptr
,你可以用Value.Elem()
得到指向的值,你可以将它的种类与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
正如您在最后一行中看到的(其中值是 *[]string
类型的 nil
指针) isPtrSlice()
returns false
while isPtrSlice2()
returns true
.