聽 聽 目前,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++的模板我还不太理解,在实践中慢慢感悟吧。
本文出自 “说话的白菜” 博客,谢绝转载!