Golang语言 - 以任意类型的slices作为输入参数
时间:2022-05-05
本文章向大家介绍Golang语言 - 以任意类型的slices作为输入参数,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
最近参与的一个业余项目,go-linq,让我了解到Go语言的类型系统并不是为任何类面向 对象编程而设计的。没有泛型,没有类型继承,也没有提供任何对这些特性有用的东西。
但是,提供了一个名为interface{}的类型,你可以向其赋予几乎任意类型的值,不会抛出编译错误,就像.NET的Object或Java的Object:
var o interface{}
o := 3.14
o := Student{Name: "Ahmet"}
我们假设你需要一个可以接收任意类型slices的函数,如果考虑如下这样实现:
func Method(in []interface{}){...}
...
slice := []int{1, 2, 3}
Method(slice) // 抛出错误
这样的代码会抛出编译错误,因为[]int不是[]interface{}。那么该如何解决这个问题呢?你可以要求Method的使用者先把slices 转换为[]interface{}类型。也就是说他们必须借助于如下类似函数将他们的[]AnyType类型参数转换为[]interface{}类型:
func conv(in []AnyType) (out []interface{}) {
out = make([]interface{}, len(in))
for i, v := range in {
out[i] = v
}
return
}
但这种实现的扩展性并不好。如果Method的使用者(可以是一个常用函数如Map、Filter等)想向Method传递N种不同类型的参数, 那么他们就必须编写N个conv函数。
对此,我们该怎么办呢?使用reflection(反射)呀!实现一个函数以interface{}(可以赋任意类型的值)为输入参数类型,在函数内部 将这个输入参数转换为一个slice,然后用于我们Method函数。如下所示:
func takeSliceArg(arg interface{}) (out []interface{}, ok bool) {
slice, success := takeArg(arg, reflect.Slice)
if !success {
ok = false
return
}
c := slice.Len()
out = make([]interface{}, c)
for i := 0; i < c; i++ {
out[i] = slice.Index(i).Interface()
}
return out, true
}
func takeArg(arg interface{}, kind reflect.Kind) (val reflect.Value, ok bool) {
val = reflect.ValueOf(arg)
if val.Kind() == kind {
ok = true
}
return
}
函数takeArg()尝试将传入的参数值转换为指定的reflect.Kind类型,然后函数takeSliceArg() 尝试将传递给它的值(经takeArg()转换后)转换为一个interface{}的slice。虽然,这样会因为反射而影响到一点性能,但影响并不大。
就是这样了。这种方案启发于Tobia Confronto的fn项目,并应用到go-linq中。
- CKEditor/CKFinder升级心得
- Docker容器学习梳理-Dockerfile构建镜像
- 再谈web开中几种经典的大文件上传组件
- Nginx负载均衡中后端节点服务器健康检查的操作梳理
- Linux系统下CPU使用(load average)梳理
- 基于组件的.NET技术(5)
- Silverlight与WPF中BeginInvoke的差异
- Linux下部署SSH登录时的二次身份验证环境记录(利用Google Authenticator)
- Linux下DNS简单部署(主从域名服务器)
- 本地yum源部署记录
- silverlight4:摄像头占用状态检测以及二种截屏方法
- Flash/Flex学习笔记(16):如何做自定义Loading加载其它swf
- 台胞也能发红包喽!小编手把手教你搞定微信支付!
- 获取可视区域高度赋值给div(解决document.body.clientHeight的返回值为0的问题)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法