关于一个展开切片变参为[]interface{}的思考

问题起因

由于在工作中使用了xorm,发现在查询的in方法里,如果传入一个切片,当切片为空的时候会返回错误,但如果传入一个变参,当变参不存在的时候,会忽略掉这个条件。

但变参的定义是interface{}类型,于是就遇到了一个需求,将各种基本类型切片传入转换为[]interface{},这样用起来更方便。

这里发一个我现在用的实现,也许大家有更好的方式,欢迎留言。

具体实现

func ToInterfaceSlice(s ...interface{}) []interface{} {
	var buf []interface{}
	for _, v := range s {
		switch reflect.TypeOf(v).Kind() {
		case reflect.Slice:
			vValue := reflect.ValueOf(v)
			for i := 0; i < vValue.Len(); i++ {
				item := vValue.Index(i).Interface()
				if reflect.TypeOf(item).Kind() == reflect.Slice {
					buf = append(buf, ToInterfaceSlice(item)...)
				} else {
					buf = append(buf, item)
				}
			}
		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
			reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64,
			reflect.Float32, reflect.Float64,
			reflect.String:
			buf = append(buf, v)
		}
	}
	return buf
}

测试代码

import (
	"fmt"
	"reflect"
)

type Int int

func main() {
	params := []interface{}{
		1,
		[]int{1, 2, 3},
		[]Int{1, 2, 3},
		[][]Int{
			{1, 2},
			{2, 3},
			{3, 4},
		},
	}
	for _, param := range params {
		fmt.Printf("input %v output %v\n", param, ToInterfaceSlice(param))
	}
	fmt.Printf("input %v output %v\n", params, ToInterfaceSlice(params...))
}

测试结果

input 1 output [1]
input [1 2 3] output [1 2 3]
input [1 2 3] output [1 2 3]
input [[1 2] [2 3] [3 4]] output [1 2 2 3 3 4]
input [1 [1 2 3] [1 2 3] [[1 2] [2 3] [3 4]]] output [1 1 2 3 1 2 3 1 2 2 3 3 4]