欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Golang 传递任意类型的切片

程序员文章站 2022-07-04 09:39:53
肯定有这样的一种场景,写一个函数,该函数可以接收任意类型的切片,完成相应的功能。 就好比这种情况 还有很多类型的切片,但是我对这些切片的使用,只是for循环每一个元素,执行Print操作就可以了。 那就定义一个函数,函数的接收参数就是这个切片就行了,但是切片类型太多了,你要根据不同的切片类型,写不同 ......

肯定有这样的一种场景,写一个函数,该函数可以接收任意类型的切片,完成相应的功能。

就好比这种情况

intslice := []int{1,2,3,4,5,6,7,8}
strslice := []string{"a","b","c","d"}
boolslice := []bool{true,true,false,true}

还有很多类型的切片,但是我对这些切片的使用,只是for循环每一个元素,执行print操作就可以了。
那就定义一个函数,函数的接收参数就是这个切片就行了,但是切片类型太多了,你要根据不同的切片类型,写不同从接收参数类型,但是函数体的代码都是一样,for循环,然后print就可以。那么有没有一种类型,可以接收所有类型的参数呢?

interface{}: 空接口这个类型,他可以接收任意类型的数据

func faa (arg interface{}) {
    fmt.println(arg)
}

func main() {
    
    faa(intslice)   
    faa(strslice)
    faa(boolslice)  // 能够成功输出,不会报错
}

但是将faa的函数体改下,执行for操作

func faa (arg interface{}) {
    for _,v := range arg {
        fmt.println(v)
    }
}

运行程序,会报错,报错信息:cannot range over arg (type interface {}), interface {}类型不能进行for循环,,那么[] interface {}这种切片类型就可以进行for了吧,

func faa (arg []interface{}) {
    for _,v := range arg {
        fmt.println(v)
    }
}

func main() {
    
    faa(intslice)   
    faa(strslice)
    faa(boolslice)  
}

这样的情况的话,我们在调用faa函数的时候,已经报错了,说类型不对,faa的接收参数类型为[]interface{},但我传递的参数类型为[]int,[]string,[]bool。所以这样是不行的。

下面是解决方法:

  • 首先faa接收的参数类型为 interface{}
  • 将arg进行转化,转为[]interface{}
  • 最后进行for循环操作

直接贴代码,我是参考别人的

该博主的博客: https://blog.csdn.net/haodawang/article/details/83931629

// interface{}转为 []interface{}
func createanytypeslice(slice interface{}) ([]interface{}, bool) {
    val, ok := isslice(slice)

    if !ok {
        return nil, false
    }

    slicelen := val.len()

    out := make([]interface{}, slicelen)

    for i := 0; i < slicelen; i++ {
        out[i] = val.index(i).interface()
    }

    return out, true
}

// 判断是否为slcie数据
func isslice(arg interface{}) (val reflect.value, ok bool) {
    val = reflect.valueof(arg)

    if val.kind() == reflect.slice {
        ok = true
    }

    return
}


// 看需求写的代码
func faa(arg interface{}) {
    slice, ok := createanytypeslice(arg)
    if !ok {
        return
    }
    for index,value := range slice {
        fmt.println(index,value)
    }
}

func main() {
    
    intslice := []int{1,2,3,4,5,6,7,8}
    strslice := []string{"a","b","c","d"}
    boolslice := []bool{true,true,false,true}
    
    
    faa(intslice)   
    faa(strslice)
    faa(boolslice)  
}