首页 >后端开发 >Golang >为什么 Go 缺乏数组/切片协方差需要解决方法来处理不同的集合类型?

为什么 Go 缺乏数组/切片协方差需要解决方法来处理不同的集合类型?

Patricia Arquette
Patricia Arquette原创
2024-12-24 02:52:13532浏览

Why Does Go's Lack of Array/Slice Covariance Require Workarounds for Handling Different Collection Types?

解决 Go 中缺乏数组/切片协方差的问题

在 Go 中,数组或切片协方差的缺失可能会在使用时带来挑战不同类型的集合。考虑以下场景:

func printItems(header string, items []interface{}, fmtString string) {
  // ...
}

func main() {
  var iarr = []int{1, 2, 3}
  var farr = []float{1.0, 2.0, 3.0}
  printItems("Integer array:", iarr, "")
  printItems("Float array:", farr, "")
}

Go 缺乏泛型,导致我们无法定义接受任何类型集合的泛型 printItems 函数。相反,我们遇到以下错误:

prog.go:26: cannot use iarr (type []int) as type []interface { } in function argument      
prog.go:27: cannot use farr (type []float) as type []interface { } in function argument

基于接口的解决方案

克服此限制的一种常见方法是采用定义所需行为的接口为了我们的收藏。在本例中,我们定义一个带有两个方法的 List 接口,At(检索特定索引处的项目)和 Len(获取列表的长度):

type List interface {
    At(i int) interface{}
    Len() int
}

然后我们创建具体的实现这个接口用于我们的整数和浮点列表:

type IntList []int
type FloatList []float64

func (il IntList)   At(i int) interface{} { return il[i] }
func (fl FloatList) At(i int) interface{} { return fl[i] }

func (il IntList)   Len() int { return len(il) }
func (fl FloatList) Len() int { return len(fl) }

有了这些实现,我们现在可以修改 printItems 函数以接受 List 作为参数,从而允许我们打印整数和浮点数组:

import "fmt"

func printItems(header string, items List) {
    for i := 0; i < items.Len(); i++ {
        fmt.Print(items.At(i), " ")
    }
    fmt.Println()
}

在我们的主函数中,我们可以使用整数和浮点列表调用 printItems,实现我们想要的结果:

func main() {
    var iarr = []int{1, 2, 3}
    var farr = []float64{1.0, 2.0, 3.0}
    printItems("Integer array:", IntList(iarr))
    printItems("Float array:", FloatList(farr))
}

通过利用接口尽管 Go 中没有泛型,但为了为我们的集合定义一组通用的操作,我们仍然可以实现一定程度的灵活性和代码可重用性。

以上是为什么 Go 缺乏数组/切片协方差需要解决方法来处理不同的集合类型?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn