美文网首页
Go 泛型初体验

Go 泛型初体验

作者: rayjun | 来源:发表于2021-08-28 19:26 被阅读0次

在 Go1.17 中,千呼万唤的泛型终于出来了,但又没有完全出来。在 Go1.17 的发布文档中,并没有提到泛型,但是眼见的网友发现,泛型相关的代码其实已经合并了,只是没有默认启用。目前来说,泛型的玩玩就行,不要用到生产中。

泛型有望在 Go1.18 版本中发布。

1. 启用泛型

泛型的功能虽然添加到 Go.1.17 中了,如果要使用,需要添加一些参数开启,首先需要安装 Go1.17:

$ go version                                                                                                                                                                                                                                                                       ~
go version go1.17 darwin/amd64

然后可以在编译 的参数中看到泛型的影子,下面的 -G 参数就是启用泛型所需要的参数:

$ go tool compile -h                                                                                                                                                                                                                                                               ~
usage: compile [options] file.go...
  -% int
        debug non-static initializers
  -+    compiling runtime
  -B    disable bounds checking
  -C    disable printing of columns in error messages
  -D path
        set relative path for local imports
  -E    debug symbol export
  -G    accept generic code

看一个例子:

package main

import (
    "fmt"
)

type Addable interface {
    type int, int8, int16, int32, int64,
        uint, uint8, uint16, uint32, uint64, uintptr,
        float32, float64, complex64, complex128,
        string
}

func add[T Addable](a, b T) T {
    return a + b
}

func main() {
    fmt.Println(add(1,2))

    fmt.Println(add("foo","bar"))
}

如果直接运行上面的代码,会报下面的错误,这也说明 Go1.17 默认是不支持泛型的:

$ go run main.go                                                                                                                                                                                                                       
# command-line-arguments
./main.go:8:2: syntax error: unexpected type, expecting method or interface name
./main.go:14:6: missing function body
./main.go:14:9: syntax error: unexpected [, expecting (

需要加上下面的参数:

$ go run -gcflags=-G=3 main.go                                                                                                                                                                                                     ↵
3
foobar

第一个泛型程序成功运行了。

2. 类型参数和约束

在 Go 泛型中,增加了两个新概念,一个是 type parameters,下面代码中的 T 就是类型参数,用来表示泛型:

func add[T Addable](a, b T) T {
    return a + b
}

可以说 type parameters 在 Go 中就是泛型的意思。

再看一下下面这段代码,这里泛型的类型是 any,上面的代码则是自定义的 Addable。

func print[T any](a T) {
     fmt.Printf("%v", a)
}

上面的 add 函数是有约束的,只能使用 Addable 中定义的类型,如果我们把 Addable 中的 string 去掉,代码就会报下面的错误:

$ go run -gcflags=-G=3 main.go
# command-line-arguments
./main.go:24:20: string does not satisfy Addable (string not found in int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr, float32, float64, complex64, complex128)

而 print 函数则可以接受任何类型的参数。

这就是 Go 中泛型最重要的两个概念:类型参数约束

3. 类型推断

正常使用泛型的时候,其实要使用下面这种方式来调用的,以 add 方法为例:

add[int](1,2)
add[string]("foo","bar")

但是按照下面的方式写代码也是合法的:

add(1,2)
add("foo","bar")

可以把泛型参数省略调,这不部分的工作其实是 Go 编译器来完成的,编译器会根据传入的实际类型来推断,而不用每次写代码的时候都指明泛型的类型。

类型推断可以让代码简洁不少。

4. 小结

Go 泛型涉及到的内容大致就是上面这些了,当然泛型也可以写出很复杂的代码,但实际上涉及到的内容也就是上面那些。总体来说还是比较简洁的,这也与 Go 的设计理念符合。

Go 泛型目前还没有正式发布,上面的内容在正式发布的时候可能也会有所调整,所以不要在生产中区使用泛型。

本文例子来源于:https://github.com/mattn/go-generics-example

文 / Rayjun

相关文章

  • Go 泛型初体验

    在 Go1.17 中,千呼万唤的泛型终于出来了,但又没有完全出来。在 Go1.17 的发布文档中,并没有提到泛型,...

  • go 泛型

    go 泛型 1. 类型参数(Type parameters) Go语言的泛型(Generic)叫做类型参数。泛型可...

  • 夯实 Java 基础1 - 泛型的使用与原理

    Java 泛型为我们写安全易读的通用程序提供了便利,Go 也将在 2.0 引入泛型。下面首先介绍 Java 泛型的...

  • Golang学习笔记---“泛型”的实现

    Golang学习笔记---“泛型”的实现 大家都知道,go语言中是没有泛型的,但是我们可以通过空接口的方式来实现泛...

  • Go语言 泛型

    本篇文章转载自 在go中使用"泛型" 在进入泛型的话题之前, 首先实现对int 数组切片的冒泡排序: 如你所见, ...

  • go泛型体验

    背景 有了泛型可以做到复用,比如sort,filter,map,reduce等常用方法,这里举个ch的例子我们写g...

  • go1.18探索 -- 泛型

    go1.18终于发布了,据说支持了泛型,今天让我来一探究竟。 安装 执行如下命令 确认安装完成 泛型讲解 先看个问...

  • 泛型 & 注解 & Log4J日志组件

    掌握的知识 : 基本用法、泛型擦除、泛型类/泛型方法/泛型接口、泛型关键字、反射泛型(案例) 泛型 概述 : 泛型...

  • go基本语法

    一、总结 1、Go没有对象,没有继承多台,没有泛型,没有try/catch2、Go有接口,函数式编程,csp并发模...

  • 【泛型】通配符与嵌套

    上一篇 【泛型】泛型的作用与定义 1 泛型分类 泛型可以分成泛型类、泛型方法和泛型接口 1.1 泛型类 一个泛型类...

网友评论

      本文标题:Go 泛型初体验

      本文链接:https://www.haomeiwen.com/subject/qbfiiltx.html