Golang 中"泛型"的支持

本文介绍在Golang中如何通过接口实现类似泛型的功能,以支持不同类型的排序操作。通过具体的冒泡排序实例,展示了如何定义通用的排序接口,并为不同类型的数据(如整数和字符串)实现该接口。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

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

package main

import (
	"fmt"
)

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]
			}
		}
	}
}

func main() {
	a1 := []int{3, 2, 6, 10, 7, 4, 6, 5}
	bubbleSort(a1)
	fmt.Println(a1)
}

上面的例子输出为:

[2 3 4 5 6 6 7 10]

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

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

  1. 查看切片长度,以用来遍历元素(Len);
  2. 比较切片中的两个元素(Less);
  3. 根据比较的结果决定是否交换元素位置(Swap)。
    到这里,或许你已经明白了,我们可以把上面的函数分解为一个支持任意类型的接口,任何其他类型的数据只要实现了这个接口,就可以用这个接口中的函数来排序了。
type Sortable interface{
	Len() int
	Less(int, int) bool
	Swap(int, int)
}

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

package main

import (
	"fmt"
)

type Sortable interface {
	Len() int
	Less(int, int) bool
	Swap(int, int)
}

func bubbleSort(array Sortable) {
	for i := 0; i < array.Len(); i++ {
		for j := 0; j < array.Len()-i-1; j++ {
			if array.Less(j+1, j) {
				array.Swap(j, j+1)
			}
		}
	}
}

//实现接口的整型切片
type IntArr []int

func (array IntArr) Len() int {
	return len(array)
}

func (array IntArr) Less(i int, j int) bool {
	return array[i] < array[j]
}

func (array IntArr) Swap(i int, j int) {
	array[i], array[j] = array[j], array[i]
}

//实现接口的字符串,按照长度排序
type StringArr []string

func (array StringArr) Len() int {
	return len(array)
}

func (array StringArr) Less(i int, j int) bool {
	return len(array[i]) < len(array[j])
}

func (array StringArr) Swap(i int, j int) {
	array[i], array[j] = array[j], array[i]
}

//测试
func main() {
	intArray1 := IntArr{3, 4, 2, 6, 10, 1}
	bubbleSort(intArray1)
	fmt.Println(intArray1)

	stringArray1 := StringArr{"hello", "i", "am", "go", "lang"}
	bubbleSort(stringArray1)
	fmt.Println(stringArray1)
}

输出结果为:

[1 2 3 4 6 10]
[i am go lang hello]

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

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

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

Golang自V1.18版本开始正式支持Golang中可用于变量、函数、方法、接口、通道等多个语法实体。的使用方法可以分为以下几个方面: 1. 变量类变量类是针对类变量的,可以用于声明包含不同类的变量。例如,可以声明一个切片变量,使其可以存储不同类的元素。 2. 自定义:在Golang中,可以通过声明自定义的来扩展的使用。这意味着可以定义适用于不同类的自定义数据结构。 3. 调用带的函数:通过使用作为函数参数或返回值,可以调用带有的函数。这样可以实现在不同类上通用的函数逻辑。 4. 与结构体:可以与结构体一同使用,结构体中的字段和方法可以是,从而实现更灵活和通用的数据结构和操作。 然而,需要注意的是,Golang还存在一些限制和缺陷。例如,无法直接与switch语句配合使用。这是因为在中无法判断具体的类,而switch语句需要根据具体类进行分支判断。 总的来说,Golang提供了一种通用的类机制,使得代码更具灵活性和可复用性。但是需要熟悉的语法和使用限制,以避免在实际使用中遇到问题。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [全面解读!Golang的使用](https://blog.youkuaiyun.com/QcloudCommunity/article/details/125401490)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [go使用方法](https://blog.youkuaiyun.com/qq_42062052/article/details/123840525)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值