zoukankan      html  css  js  c++  java
  • Golang 传递任意类型的切片

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

    就好比这种情况

    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)  
    }
    
  • 相关阅读:
    函数的重载 C++快速入门06
    PE格式详细讲解8 系统篇08|解密系列
    《零基础入门学习汇编语言》检测点,实验,课后题答案
    PE格式详细讲解9 系统篇09|解密系列
    C++输出输入小结 C++快速入门05
    使用XML生成菜单
    DNS解析过程详解
    Windows Azure 2.5天深度技术训练营 和 微软公有云发现之旅
    使用单例模式实现自己的HttpClient工具类
    android 反编译和防止被反编译。
  • 原文地址:https://www.cnblogs.com/zhuchunyu/p/11253400.html
Copyright © 2011-2022 走看看