[2012-05-21 翻译自这里, 对原文有所扩展, 也有所删减. 版权属于原作者, 转载必须保留此声明.]
在进入泛型的话题之前, 首先实现对int slice(可以看做int数组)的冒泡排序:
func BubbleSort(array []int) {
for i := 0; i < len(array); i++ {
for j := 0; j < len(array)-i-1; j++ {
if array[j] > array[j+1] {
// 交换
array[j], array[j+1] = array[j+1], array[j]
}
}
}
}
如你所见, 上面的代码仅适用于对int数组进行排序, 如果想要对string数组排序, 不得不另写一个.
是否可以只写一个通用的泛型程序, 以便对所有类型的数组(甚至是任意数据)进行冒泡排序?
很遗憾, go不支持java中的标记式泛型. 但是我们可以使用go的interface实现类似的功能.
interface用于定义方法的集合. 在冒泡排序中, 我们可以将排序操作分解成3个方法: Len()方法负责计算长度, Less(i, j)方法负责比较大小, Swap(i, j)方法负责进行交换.
// 定义可排序接口
type Sortable interface {
Len() int
Less(int, int) bool
Swap(int, int)
}
可以说, 任何实现了Sortable接口的数据类型都可进行冒泡排序, 下面是对Bubblesort方法的改造:
func BubbleSortable(arr Sortable) {
length := arr.Len()
for i := 0; i < length; i++ {
for j := i; j < length-i-1; j++ {
if arr.Less(j, j+1) {
arr.Swap(j, j+1)
}
}
}
}
BubbleSortable函数可以对所有Sortable类型的数据进行排序. 那么, 哪些数据是Sortable类型的呢? 很简单, 那些实现了Len(), Less(i, j), Swap(i, j)方法的数据类型都是Sortable的.
如果想要对int数组进行冒泡排序, 只需让int数组实现以上3个方法即可:
// 定义IntArr类型
type IntArr []int
// 给IntArr提供Len方法
func (arr IntArr) Len() int {
return len(arr)
}
// 给IntArr提供Less方法
func (arr IntArr) Less(i int, j int) bool {
return arr[i] < arr[j]
}
// 给IntArr提供Swap方法
func (arr IntArr) Swap(i int, j int) {
arr[i], arr[j] = arr[j], arr[i]
}
至此, 我们定义了新的类型: IntArr(实际上就是int数组), 并为IntArr增加了Len, Less, Swap方法.
注意, 在go中, 实现接口不需要像java那样显式的说明对某个接口的implements, 只需要为类型提供所有interface中定义的方法即可. 此例中, 我们给IntArr提供了所有Sortable中定义的方法, 所以IntArr已经实现了Sortable接口. 接下来要做的是将IntArr类型的数据传递给BubbleSortable函数就可以了:
intarr := IntArr{2, 3, 1, -9, 0}
// 调用排序方法
BubbleSortable(intarr)
// 输出排序之后的数据
fmt.Printf("sorted int arr is: %v\n", intarr)
同样的, 如果想对string数组进行冒泡排序, 也只需要让string数组实现Sortable接口中定义的所有方法:
type StrArr []string
func (arr StrArr) Len() int {
return len(arr)
}
func (arr StrArr) Less(i int, j int) bool {
return arr[i] < arr[j]
}
func (arr StrArr) Swap(i int, j int) {
arr[i], arr[j] = arr[j], arr[i]
}
测试代码如下:
strarr := StrArr{"nut", "ape", "elephant", "zoo", "go"}
Bubblesort(strarr)
fmt.Printf("sorted string arr is: %v\n", strarr)
现在, 你可以对任意数据进行冒泡排序了, 只需要该类型实现了Len, Less, Swap方法.
分享到:
相关推荐
Grizzly允许您在GO中使用集合,而不用泛型。 使用Grizzly,您可以使用Map,过滤器,查找等方法。
Go-mapstructure-Go库用于解码泛型map值成Go结构体
主要介绍了Golang 使用接口实现泛型的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
Go泛型示例代码go-generics-example用法$ go build -gcflags = -G = 3要求Go 1.17或更高版本广告进入Go语言的泛型为我们带来了什么?又名mattn)
Go语言有时候被描述为“C类似语言”,或者是“21世纪的C语言”... Go语言有足够的类型系统以避免动态语言中那些粗心的类型错误,但是Go语言的类型系统相比传统的强 类型语言又要简洁很多。虽然有时候这会导致一个“无类
GoJSON解析JSON在golang中很麻烦。 这个包将允许您解析和搜索json中没有结构的元素。 安装gojson go get github.com/swaraj1802/GoJSON/gojson用法导入import“ github.com/swaraj1802/GoJSON/gojson”示例代码...
您可以使用最新的Go tip版本在此存储库中构建所有代码示例。 $ git clone https://github.com/golang/go && cd src && ./all.bash $ ../bin/go test -gcflags=all=-G=3 -v ./... -gcflags=all=-G=3是使用类型参数...
用go语言实现的结构体排序,使用go的反射包(reflect),实现结构体按指定字段排序,字段类型目前支持int,int64,string,方便扩展任意基本类型,使用直接导入包,然后调用sortStruct(structArr, 'sorft_name', ...
gomacro - 具有REPL,Eval,泛型和类似Lisp宏的交互式Go解释器和调试器
list集合泛型等常用
仿制药Go泛型的快速实验algebra ,浮点型,复数型和有理数的通用平方根函数。 concur ,各种并发实用程序。 future ,并发缓存(“未来缓存”)。 mapreduce ,并行Map,Reduce和ForEach实用程序maps ,具有基于...
【go语言学习资料】Go语言基础和进阶以及学习Go语言的一些感悟.zip 【资源介绍】 CGO、go_compile、HTTP、kafka_learning、pprof、unit_test、并发基础、底层编程、泛型、内存管理、设计模式、注入、 CGO、go_...
各类模式的模仿,和通用思想,熟悉编程的人都知道,以GO语言的思想参考
在此仓库中查看cmd / benchmarks应用程序。 可以在简单类型和结构上运行的完整JSONPath实现。 泛型类型。 不是建议的golang泛型,而是键入安全的JSON元素。 快速的JSON验证程序(使用io.Reader的速度快4倍)。 具有...
这意味着通用函数和类型只能在那个文件中使用。 这是一个简单的例子。 // reverse.go package main import "fmt" func Reverse ( a [] type T ) { for i , j := 0 , len ( a ) - 1 ; i < j ; i , j = i + 1 , j -...
是的,除了C++那样的泛型,了解其它编程语言你一定会发现,在动态类型语言或是某些有语法糖支持的语言中,那个swap() 或 search() 函数的泛型其实可以
创世记 缺少用于切片和通道的golang通用stdlib。...在一片整数中找到最小值: s := [] int { 42 , 7 , 13 } min := genesis. SliceInt { s }. Min () 整数部分中的双精度值: s := [] int { 4 ,
在1.8版本中开放插件(Plugin)的支持,这意味着现在能从Go中动态加载部分函数。 与C++相比,Go并不包括如枚举、异常处理、继承、泛型、断言、虚函数等功能,但增加了 切片(Slice) 型、并发、管道、垃圾回收、接口...
goderive goderive派生了您不想维护的普通golang函数,并使它们保持最新状态。...示例在下面的代码中,将发现generateEqual函数是未实现(或先前已推导)且具有前缀deriveEqual的函数。 包主要类型MyStru