在go中使用"泛型"
程序员文章站
2022-04-18 18:32:44
...
[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方法.
推荐阅读
-
在ASP.NET Core 3.0中使用Swagger
-
在Word2010中使用“插入表格”对话框插入表格
-
在Word2010中使用快捷键输入10以上带圈数字
-
SqlServer2005中使用row_number()在一个查询中删除重复记录的方法
-
web.py在SAE中的Session问题解决方法(使用mysql存储)
-
使用PDF.JS插件在HTML中预览PDF文件的方法
-
在Asp.Net或.Net Core中配置使用MarkDown富文本编辑器有开源模板代码(代码是.net core3.0版本)
-
ASP.NET Core 3.0 : 二十八. 在Docker中的部署以及docker-compose的使用
-
在Asp.Net Core中配置使用MarkDown富文本编辑器实现图片上传和截图上传(开源代码.net core3.0)
-
分析在Python中何种情况下需要使用断言