Golang 中"泛型"的支持

Posted Golang语言社区

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Golang 中"泛型"的支持相关的知识,希望对你有一定的参考价值。

Golang不支持一般的类似java中的标记式泛型。很多人因此而十分不满,认为没有泛型增加了很多工作量。而目前由于泛型支持的复杂性,Golang的设计和实现者并没有把这个泛型支持作为紧急需要增加的特性。但是,如果真的没有泛型,就一定不行了么?答案当然是否定的。没有泛型也可以,而且我觉得代码更简单,直接,有趣(个人观点,勿喷)。

我们这里打算以一些例子来讲解Golang中如何处理这个问题。

首先,我们看一个冒泡排序的问题。针对整型数组切片的排序。

  1. package main


  2. import (

  3.         "fmt"

  4. )


  5. func bubbleSort(array []int) {

  6.         for i := 0; i < len(array); i++ {

  7.                 for j := 0; j < len(array)-i-1; j++ {

  8.                         if array[j] > array[j+1] {

  9.                                 array[j], array[j+1] = array[j+1], array[j]

  10.                         }

  11.                 }

  12.         }

  13. }


  14. func main() {

  15.         a1 := []int{3, 2, 6, 10, 7, 4, 6, 5}

  16.         bubbleSort(a1)

  17.         fmt.Println(a1)

  18. }

复制代码

上面的例子输出为:

  1. [2 3 4 5 6 6 7 10]

复制代码

那么,我们如果希望这个bubbleSort能够同时支持float类型数据排序,或者是按照字符串的长度来排序应该怎么做呢?在其他的例如java语言中,我们可以将bubbleSort定义为支持泛型的排序,但是Go里面就不行了。为了达到这个目的,我们可以使用interface来实现相同的功能。

针对上面的排序问题,我们可以分析一下排序的步骤:

  • 查看切片长度,以用来遍历元素(Len);

  • 比较切片中的两个元素(Less);

  • 根据比较的结果决定是否交换元素位置(Swap)。
    到这里,或许你已经明白了,我们可以把上面的函数分解为一个支持任意类型的接口,任何其他类型的数据只要实现了这个接口,就可以用这个接口中的函数来排序了。

    复制代码

    下面,我们就用几个例子来描述一下这个接口的用法。

    复制代码

    输出结果为:

    复制代码

    上面的例子中,我们首先定义了一个IntArr类型的整型切片类型,然后让这个类型实现了Sortable接口,然后在测试代码中,这个IntArr类型就可以直接调用Sortable接口的bubbleSort方法了。

    另外,我们还演示了一个字符串切片类型StringArr按照字符串长度来排序的例子。和IntArr类型一样,它实现了Sortable即可定义的方法,然后就可以用Sortable即可的bubbleSort方法来排序了。

    总结
    上面的例子,是一种Golang中支持所谓的“泛型”的方法。这种泛型当然不是真正意义上面的泛型,但是提供了一种针对多种类型的一致性方法的参考实现。

    1. [1 2 3 4 6 10]

    2. [i am go lang hello]

    1. package main


    2. import (

    3.         "fmt"

    4. )


    5. type Sortable interface {

    6.         Len() int

    7.         Less(int, int) bool

    8.         Swap(int, int)

    9. }


    10. func bubbleSort(array Sortable) {

    11.         for i := 0; i < array.Len(); i++ {

    12.                 for j := 0; j < array.Len()-i-1; j++ {

    13.                         if array.Less(j+1, j) {

    14.                                 array.Swap(j, j+1)

    15.                         }

    16.                 }

    17.         }

    18. }


    19. //实现接口的整型切片

    20. type IntArr []int


    21. func (array IntArr) Len() int {

    22.         return len(array)

    23. }


    24. func (array IntArr) Less(i int, j int) bool {

    25.         return array[i] < array[j]

    26. }


    27. func (array IntArr) Swap(i int, j int) {

    28.         array[i], array[j] = array[j], array[i]

    29. }


    30. //实现接口的字符串,按照长度排序

    31. type StringArr []string


    32. func (array StringArr) Len() int {

    33.         return len(array)

    34. }


    35. func (array StringArr) Less(i int, j int) bool {

    36.         return len(array[i]) < len(array[j])

    37. }


    38. func (array StringArr) Swap(i int, j int) {

    39.         array[i], array[j] = array[j], array[i]

    40. }


    41. //测试

    42. func main() {

    43.         intArray1 := IntArr{3, 4, 2, 6, 10, 1}

    44.         bubbleSort(intArray1)

    45.         fmt.Println(intArray1)


    46.         stringArray1 := StringArr{"hello", "i", "am", "go", "lang"}

    47.         bubbleSort(stringArray1)

    48.         fmt.Println(stringArray1)

    49. }

    1. type Sortable interface{

    2.         Len() int

    3.         Less(int, int) bool

    4.         Swap(int, int)

    5. }

以上是关于Golang 中"泛型"的支持的主要内容,如果未能解决你的问题,请参考以下文章

Spring mvc HandlerInterceptor 怎样获取 rest 参数值

java泛型-“扩展”关键字->不支持添加元素

java的多线程在golang中是如何体现的

如何看待go语言泛型的最新设计?

golang中string类型的数组字典如何提取?

关于Java泛型"擦除"的一点思考