初探 golang 1.18 generics 功能
source link: https://blog.wu-boy.com/2022/02/introduction-to-golang-1-18-generics/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Go 語言在近期內會推出 1.18 版本,而 1.18 最重要的功能之一就是 generics,在此版本之前,最令人詬病的就是 Go 無法支援多種 Type 當參數,造成在寫 Package 時候多出很多重複性的程式碼,本篇會教大家基礎認識什麼是 generics,及怎麼使用。
影片視頻會同步放到底下課程內
安裝 1.18 及整合 Vscode 編輯器
首先要先安裝 go1.18 beta2 版本,方式很簡單,請參考底下
go install golang.org/dl/go1.18beta2@latest
go1.18beta2 download
完成後可以透過底下指令看到 go1.18beta2
$ go1.18beta2 env GOROOT
/Users/mtk10671/sdk/go1.18beta2
如果要快速嘗試用 go
指令,可以直接透過 alias 指令
alias go=go1.18beta2
該如何整合到 Vscode 內呢?請參考這篇文章,幾個步驟就可以完成。第一個步驟就是請把 go1.18beta2
變成環境變數預設值 PATH
,請改成
PATH="$HOME/sdk/go1.18beta2/bin:$PATH"
打開 VSCODE 編輯器,重新安裝全部 tools,直接 cmd + shift + p
選擇 Go: Install/Update Tools
,把全部 toll 打勾重新安裝。最後步驟就是打開預設的 config.json 檔案加上
"gopls": {
"ui.semanticTokens": true
}
使用 generic
我們來寫一個 func 支援一個參數,此參數可以是 int64
或 float64
型態,線上執行
package main
import "fmt"
func show[num int64 | float64](s num) {
fmt.Println(s)
}
func main() {
fmt.Println("go 1.18 Generics Example")
var sum1 int64 = 28
var sum2 float64 = 29.5
show(sum1)
show(sum2)
}
大家可以看到 [num int64 | float64]
定義一個新的型態,此型態可以為 int64
或 float64
,再把這型態放到後面。不過如果支援型態很多的話,可以改寫如下,線上執行
package main
import "fmt"
type age interface {
int8 | int16 | int32 | int64 | float32 | float64
}
func show[num age](s1 num) {
val := float64(s1) + 1
fmt.Println(val)
}
func main() {
fmt.Println("go 1.18 Generics Example")
var sum1 int64 = 28
var sum2 float64 = 29.5
show(sum1)
show(sum2)
}
在程式碼內定義一個新的 interface 將所有型態放入即可
type age interface {
int8 | int16 | int32 | int64 | float32 | float64
}
如果要支援多個參數可以怎麼寫
func total[num age](s1, s2 num) {
val := float64(s1) + float64(s2)
fmt.Println(val)
}
這樣就可以同時帶入兩個一樣的參數型態。如果要帶入不同的型態,第一個參數是 int64
,第二個是 float64
,請改成如下
func summary[num1, num2 age](s1 num1, s2 num2) {
val := float64(s1) + float64(s2)
fmt.Println(val)
}
完整測試程式碼可以參考底下,線上執行
package main
import "fmt"
type age interface {
int8 | int16 | int32 | int64 | float32 | float64
}
func newGenerics[num age](s1 num) {
val := float64(s1) + 1
fmt.Println(val)
}
func total[num age](s1, s2 num) {
val := float64(s1) + float64(s2)
fmt.Println(val)
}
func summary[num1, num2 age](s1 num1, s2 num2) {
val := float64(s1) + float64(s2)
fmt.Println(val)
}
func main() {
fmt.Println("go 1.18 Generics Example")
var sum1 int64 = 28
var sum2 float64 = 29.5
newGenerics(sum1)
newGenerics(sum2)
var sum3 float64 = 28
var sum4 float64 = 29.5
total(sum3, sum4)
var sum5 int64 = 28
var sum6 float64 = 29.5
summary(sum5, sum6)
}
最後我們來看一個例子泡沫排序 (Bubble sort)
package main
import "fmt"
// conver to generics type to support int and float64 types
func bubbleSort(array []int) []int {
for i := 0; i < len(array)-1; 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]
}
}
}
return array
}
func main() {
array := []int{11, 14, 3, 8, 18, 17, 43}
fmt.Println(bubbleSort(array))
}
除了支援 int
之外,也請支援 float64
。請直接看底下解答,線上執行
package main
import "fmt"
// The Time Complexity of the Bubble Sort is O(n^2) since it takes two nested loops to check the adjacent element.
// For example, let’s take the following unsorted array −
// 22 15 11 45 13
// Bubble Sort Algorithm first traverses the whole array and then in another loop checks if the adjacent elements are in order or not.
// Thus, after sorting the elements will be,
// 11 13 15 22 45
// conver to generics type to support both int and float64 types
type Number interface {
int | int32 | int64 | float32 | float64
}
func bubbleSort[n Number](array []n) []n {
for i := 0; i < len(array)-1; 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]
}
}
}
return array
}
func main() {
n1 := []int{11, 14, 3, 8, 18, 17, 43}
fmt.Println(bubbleSort(n1))
n2 := []float64{11.1, 14.2, 3.3, 8.4, 18.5, 17.6, 43.7}
fmt.Println(bubbleSort(n2))
}
終於有機會可以優化一些 Package 的寫法,不過為了向下相容,原本的 go1.17 寫法還是會保留,透過 go build tag 方式來決定不同的使用環境即可。
See also
Recommend
-
39
前言 最近在学习fabric 1.2版本的新特性,其中有一个是实现了交易背书和区块结果验证这两个原本由系统链码 escc 和 vscc 负责的模块的可插拔。它们的可插拔用到了Go的plugin技术,这也是我第...
-
32
golang初探之环境搭建 众所周知学习一门编程语言最重要的是入门。而入门第一步就是开发环境的搭建。下面就来简单介绍一下golang开发环境的搭建。 一、下载GO语言安装包和安装 这里给出官方下载地址。请...
-
7
Proposal: Go should have generics Author: Ian Lance Taylor Created: January 2011 Last updated: April 2016 Discussion at
-
13
how to update APIs for generics #48287 ...
-
7
This post is part of a series where I do my best to organize my thoughts around Go: its paradigms and usability as a programming language. I write this as a Java programmer that r...
-
3
Generics and Value Types in GolangAndy ArthurApril 1, 2022TECHNICALGOLANG9 min readGo 1.18 has been released...
-
10
TechBlogGenerics in Golang 1.18, no need to write max / min anymore (maybe)June 08, 20210 Comments
-
7
编辑导语:本文作者从视频搜索的特点、优势、存在问题和未来发展等方面,以具体的视频平台为例,对不同平台中视频搜索的特点进行了分析,感兴趣的小伙伴们一起来看一下吧。
-
5
参考learning gem5的part II部分进行gem5的学习。 主要工作: 自定义实现了一个简单的SimpleObject,并将其成功在gem5中执行; 将SimpleObject扩展为MemoryObject,并将其分别与CPU的i-cache/d-cache端口和内存总线相连; 输...
-
6
5/5 - (2 votes) The wait is finally over as Go has introduced its much-anticipated feature, Golang Generics, with the release of version 1.18. We’re thrilled to dive into this fascinatin...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK