Golang泛型函数

目前,golang还不支持模板函数(类型参数化),所以看上去不得不为每一种类型都实现一个函数。但是Golang可以利用空接口interface{}和闭包/高阶函数来实现泛型函数。

1 空接口

空接口interface{}是指方法集为空的接口,任何类型的值都可以赋值给空接口。接口相关内容请参见另一篇博客《Golang中的接口

// interface{}
func minimum(first interface{}, rest ...interface{}) interface{} {
    minimum := first
    for _, x := range rest {
        switch x := x.(type) {
        case int:
            if x < minimum.(int) {
                minimum = x
            }
        case float64:
            if x < minimum.(float64) {
                minimum = float64(x)
            }
        case string:
            if x < minimum.(string) {
                minimum = string(x)
            }
        }
    }

    return minimum
}

func main() {
    i := minimum(4, 5, 1, 9, 0, -1, -5, 7)
    fmt.Println(i)

    j := minimum(4.5, 5.2, -0.4, 9.9, 2.1)
    fmt.Println(j)

    k := minimum("abc", "def", "xyz", "ctz", "{}", "#$%^&* ", "中国")
    fmt.Println(k)
}

运行结果

2 闭包/高阶函数

所谓闭包就是一个函数“捕获”了和它在同一作用于的其他常量和变量,从形式上看匿名函数都是闭包。闭包相关内容请参见另一篇博客《golang闭包

// closure
funcfilter(limit int, predicate func(int) bool, appender func(int)) {
    for i := 0; i < limit; i++ {
        if predicate(i) {
            appender(i)
        }
    }
}
 
 
func main() {
    a := []int{4, -3, -8, 9, 0, 2, 1}
    even := []int{}
    filter(len(a), func(i int) bool { returna[i]%2 == 0 }, func(i int) { even = append(even, a[i]) })
    fmt.Println(even)
}

运行结果

上述两个例子非常巧妙的实现了泛型功能,可见golang“难以置信的灵活和强大”。

不过,至于golang为何不实现类似C++的模板我还不太理解,在实践中慢慢感悟吧。

时间: 2024-08-10 23:15:28

Golang泛型函数的相关文章

golang 查找数组中最小数的泛型函数

golang里要实现查找数组最小数的泛型函数,需要用到类型开关. gol的类型开关写法: switch v.(type) {        case int:        case float64:        case string: } 思路就是遍历数组,遇到更小的数保存下来,函数退出返回那个数. golang代码: package main import (     "fmt" ) func Minimum(first interface{}, rest ...interfa

C++泛型函数及模版类

什么是泛型编程? 简单来说,泛型编程,意思就是针对广泛类型的编程方式.具体类型可以有不同的实现方式,但是针对广泛类型编程,就能在需要调用时才指定参数类型或者调用类型. 泛型编程是一种基于发现高效算法的最抽象表示的编程方法.也就是说,以算法为起点并寻找能使其工作并且有效率的工作的最一般的必要条件集. 可以想象的是,很多算法都需要相同的必要条件集,并且这些必要条件集有不同的实现方式.STL标准模版库就是泛型编程的例子. 泛型函数怎么写? #include<iostream> using names

Scala 深入浅出实战经典 第42讲:scala 泛型类,泛型函数,泛型在spark中的广泛应用

王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-64讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 腾讯微云:http://url.cn/TnGbdC 360云盘:http://yunpan.cn/cQ4c2UALDjSKy 访问密码 45e2 技术爱好者尤其是大数据爱好者 可以加DT大数据梦工厂的qq群 DT大数据梦工厂① :462923555 DT大数据梦工厂②:437123764 DT大数据梦工厂③

Swift泛型和泛型函数

泛型(generic)可以使我们在程序代码中定义一些可变的部分,在运行的时候指定.使用泛型可以最大限度地重用代码.保护类型的安全以及提高性能.在Swift集合类中,已经采用了泛型.一.一个问题的思考怎样定义一个函数来判断两个参数是否相等呢?如果参数是Int类型,则函数定义如下:func isEqualsInt(a:Int, b:Int) -> Bool {    return (a == b)}这个函数参数列表是两个Int类型,它只能比较两个Int类型参数是否相等.如果我们想比较两个Double

泛型函数Func&lt;&gt;

  泛型函数,即可以接受任何类型的通用函数(有where约束除外). 例如:调用GetCacheData<int>,那第二个委托参数就是Func<int>,这个函数返回值也是int 调用GetCacheData<string>,那第二个委托参数就是Func<string>,这个函数返回值是string public static int StrToInt(String s){ return int.Parset(s); } public static voi

Java泛型函数的运行时类型检查的问题

在一个数据持久化处理中定义了数据保存和读取的 泛型函数的,但是在运行时出现类型转换错误,类型不匹配,出错的位置不是load方法,而是在调用load方法之后,得到了列表数据,对列表数据进行使用时出现的.结果列表里面的元素实际是A类型,调用load方法传递的是B类型的class,但是仍然load成功. 很是疑惑,最终修改代码调试后,解决问题. import android.content.Context; import android.text.TextUtils; import java.io.F

指针数组,数组指针,函数指针,main函数实质,二重指针,函数指针作为参数,泛型函数

 1.指针数组 数组里面的每个元素都是指针. 指针数组的案例如下: 易犯错误: 2.数组指针 归根结底还是指针,只是取*的时候能够取出一整个数组出来. 数组指针:(一个指针指向了数组,一般和二维数组搭配使用). 下面的(p+1)表示的是加过20个字符. 3.函数指针: 在gcc编译的时候增加一些调试信息的方式是: gcc demo.c –g –o app   -g表示增加一些调试信息 objdump –dSsx app > file   将app反汇编,然后重定向到file文件中.函数指针定

golang的函数

在golang中, 函数是第一类值(first-class object), 即函数可以赋值与被赋值. 换言之, 函数也可以作为ReceiverType, 定义自己的method. 实例: http.HandleFunc(pattern string, handler func(ResponseWriter, *Request)) 就是使用上述思想实现. type HandlerFunc func(ResponseWriter, *Request) func (f HandlerFunc) Se

Golang理解-函数变量

函数变量 函数作为变量值 函数变量是把函数作为值保存到变量中. 在Golang中,,函数也是一种类型,可以和其他类型一样被保存在变量中.例如: package main // 将函数作为值保存到变量中 import ( "fmt" ) func fire() { fmt.Println("fire") } func main(){ f := fire() // 将变量f声明为func()类型,此时f就被俗称为"回调函数", 此时f的值为nil f