英文:
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
是一个指针。
英文:
I know how to check if an interface is a pointer:
func isPointerArray(i interface{}) bool {
if i == nil {
return false
}
if reflect.ValueOf(i).Kind() != reflect.Ptr {
return false
}
}
But how can I check if that pointer is a slice? TypeOf
is a pointer.
答案1
得分: 6
如果值的类型是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
。可以理解,因为没有指向的值其类型可能是切片。这可能是你想要的,也可能不是。
如果你希望即使对于nil
指针值(指向切片类型的指针),也返回true
,你可以使用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()
返回false
,而isPtrSlice2()
返回true
。
英文:
If the value's kind is reflect.Ptr
, you may use Value.Elem()
to get the pointed value, and you may compare its kind to reflect.Slice
.
This is how it would look like:
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
}
But there's one catch though. If the value passed is a pointer to slice type but the value itself is the nil
pointer, this will report false
. Understandable, as there is no pointed value whose type could be a slice. This may or may not be what you want.
If you want true
even for nil
pointer values (that are of pointer to slice types), you may use reflect.Type
instead of reflect.Value
. This works for nil
pointers too, because even though there is no pointed value, there is still a pointed type (called the base type).
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
}
Testing the above functions:
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))
}
Which will output (try it on the 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
As you can see in the last line (where the value is a nil
pointer of type *[]string
) isPtrSlice()
returns false
while isPtrSlice2()
returns true
.
答案2
得分: 0
你可以使用type assertions:
package main
import "fmt"
func main() {
var value interface{}
value = &[]int{1, 2}
if res, ok := value.(*[]int); ok {
fmt.Println(res)
}
}
英文:
You can use type assertions:
package main
import "fmt"
func main() {
var value interface{}
value = &[]int{1, 2}
if res, ok := value.(*[]int); ok {
fmt.Println(res)
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论