当前位置: 首页 > 科技观察

你还没有体验过泛型吗?

时间:2023-03-13 00:12:29 科技观察

介绍之前看过一些官方通用的文章,但是没试过。有没有人还没搞定,那么末班车来了。不管学什么,先从官网拿个例子。这段代码非常简单。它定义了两个函数并计算相应传入映射值的总和。两个函数最大的区别在于函数参数类型不同。一个map的值类型是int64,一个是float64,对应的返回参数也不一样。如果没有泛型,每种类型都必须重新定义一个函数。可能有人会说,你把上面的代码写在一个函数里这样,你确定这样真的好吗?泛型函数但是,有了泛型,事情就简单多了。上面代码中定义了一个新的函数SumIntsOrFloats,它声明了两个类型参数[Kcomparable,Vint64|浮动64]。其中K指定类型必须是可比较的(即可以用作比较器==和!=)。因为go规定map的key必须是可比较的类型。例如,我们不能像这样声明一个映射。所以这里的K不能使用any关键字。另一个V参数指定一个由int64和float64组成的约束,使用|指定联合类型。所以函数中的m参数是map[K]V类型,K和V是参数type指定的类型。如果你传入的map值的类型是其他类型。例如,以下将不起作用。类型约束你在上面看到的是我们对方法的参数有一些约束。当然,我们也可以直接声明类型约束。上面的代码声明了一个用作类型约束的Number接口类型。在接口中声明int64和float64联合类型。在SumNumbers中,如果约束类型是int64或者float64,只需要使用Number类型约束,不用写int64|float64针对每个不同的函数,达到代码复用的效果。但是如果我这样做,我们将map中的值类型调整为自定义的otherInt64类型,otherInt64的基类型也是int64。但是,此代码编译时出错。原因是int64约束会限制它只能是这个类型,也就是只能是int64,而不是基于这个类型定义的其他类型。如果要使用otherInt64怎么办?这很简单。你只需要一个~符号。使用~xxtype会将其限制为基类型为xxtype的所有类型。应用上面只是简单的介绍了泛型的使用姿势,那么在哪些场景下可以使用泛型呢?在日常开发中,一些处理函数,比如slice、map、channel,可能逻辑相同但类型不同,导致多个不同的函数,这个时候可以用泛型来解决。例如,有一些行为方面。比如go中的排序,通过泛型,不需要每个结构体都实现三个方法(Len、Less、Swap),而是将依赖于三个方法的行为抽象出来。最终排序的实现只需要依赖定义的抽象即可。其他应用可以自行体验。综上所述,本文主要带大家体验一下泛型的基本使用以及对应的类型约束。最后,我们简单地试验了两个通用的场景演示。有兴趣的可以自行体验。更多内容欢迎在区内留言交流。附录https://go.dev/doc/tutorial/genericshttps://teivah.medium.com/when-to-use-generics-in-go-36d49c1aeda