如何检查接口是不是是指向切片的指针

Posted

技术标签:

【中文标题】如何检查接口是不是是指向切片的指针【英文标题】:How to check if interface is a a pointer to a slice如何检查接口是否是指向切片的指针 【发布时间】:2021-12-09 00:17:30 【问题描述】:

我知道如何检查接口是否为指针:

func isPointerArray(i interface) bool 
    if i == nil 
        return false
    
    if reflect.ValueOf(i).Kind() != reflect.Ptr 
        return false
    

但是如何检查该指针是否为切片? TypeOf 是一个指针。

【问题讨论】:

【参考方案1】:

如果值的种类是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

正如您在最后一行中看到的(其中值是 nil 类型的指针 *[]stringisPtrSlice() 返回 falseisPtrSlice2() 返回 true

【讨论】:

对于数组,可以使用reflect.Array,例如elem.Kind() == reflect.Slice || elem.Kind() == reflect.Array 那里有一些 icza 质量响应。谢谢【参考方案2】:

你可以使用type assertions:

package main

import "fmt"

func main() 
    var value interface
    value = &[]int1, 2

    if res, ok := value.(*[]int); ok 
        fmt.Println(res)
    

【讨论】:

一个限制是我不知道类型。

以上是关于如何检查接口是不是是指向切片的指针的主要内容,如果未能解决你的问题,请参考以下文章

Go语言 | 03 数组指针切片用法

Go语言 | 03 数组指针切片用法

Golang 指向切片的指针

复制一片指针(指向新值)

Go 切片

Go 向函数传递切片该使用值还是指针?