go 泛型简明教程

请在1.18后再使用泛型

本文代码来自Tutorial: Getting started with generics 目前还比较简陋,这篇文章(指本人写的),会持续更新。

看第一个例子

// 累加int
func SumInts(m map[string]int64) int64 {
    var s int64
    for _, v := range m {
        s += v
    }
    return s
}

// 累加float
func SumFloats(m map[string]float64) float64 {
    var s float64
    for _, v := range m {
        s += v
    }
    return s
}
复制代码

调用的时候就是这样的:

func main() {
    // 初始化int map 
    ints := map[string]int64{
        "first":  34,
        "second": 12,
    }

    // 初始化float map
    floats := map[string]float64{
        "first":  35.98,
        "second": 26.99,
    }

    fmt.Printf("Non-Generic Sums: %v and %v\n",
        SumInts(ints),
        SumFloats(floats))
}
复制代码

这两个函数很明显可以二合一呀。 所以,go在1.18中加了一个类型申明

func[在这里写啦!]()
复制代码

如上面的就可以整活整成:

func SumIntsOrFloats[K comparable, V int64 | float64](m map[K]V) V
复制代码

comparable是自适应的类型,加|可以表明可以是两个类型,怎么样,是不是有ts那味了?

更具体的实现如下:

func SumIntsOrFloats[K comparable, V int64 | float64](m map[K]V) V {
    var s V
    for _, v := range m {
        s += v
    }
    return s
}
复制代码

另人比较费解的就是什么时候使用comparable了。

It allows any type whose values may be used as an operand of the comparison operators == and !=. Go requires that map keys be comparable. 它允许用==和!=表达示的值。Go要求map键具有可比性

如果需要在多个地方使用,那么可以用

type Number interface {
    int64 | float64
}
复制代码

省得到处写联合类型。

func SumNumbers[K comparable, V Number](m map[K]V) V {
    var s V
    for _, v := range m {
        s += v
    }
    return s
}
复制代码

但是! 在其它地方用Type是不行的,只能用在[]中。

  1. m:= map[string]Number 是不行的
  2. func ReturnSomthing() Number { return 1} 还是不行的

any 可以替换interface{},就像这样:

m:= map[string]any{
        "1": 2,
        "2":"GKD!",
    }
复制代码

1.18出了泛型了,会对go以后产生什么影响,目前2022-04-17还看不到剧烈的变化,但是目前只能预知一个:go的面试题又要小卷一下了。 我觉得go很不错。:) 欢迎其它兄弟萌试一试,反正免费。

猜你喜欢

转载自juejin.im/post/7087528794873380894