欧美free性护士vide0shd,老熟女,一区二区三区,久久久久夜夜夜精品国产,久久久久久综合网天天,欧美成人护士h版

首頁綜合 正文
目錄

柚子快報邀請碼778899分享:Golang 泛型詳解

柚子快報邀請碼778899分享:Golang 泛型詳解

http://yzkb.51969.com/

文章目錄

1. 泛型的類型形參2. 泛型定義4. ~ :指定底層類型3. 類型約束

Go1.18 版本發(fā)布了泛型。

1. 泛型的類型形參

假如我們需要一個計算兩個數(shù)之和的函數(shù),如下定義:

package main

import (

"fmt"

)

// 變量 x, y 為函數(shù)的形參(parameter),int 形參類型

func Sum(x, y int) int {

return x + y

}

func main() {

var a, b int = 2, 6

// 變量 a, b 為調(diào)用函數(shù)的實參(argument)

fmt.Println(Sum(a, b))

}

上例 Sum 函數(shù)僅支持計算 int 類型的數(shù)值,無法計算 int32、float32 等類型的和。

若我們把 int、int32、float32 這些類型作為類型形參代替 int 告訴 Sum 我們所計算的類型是什么,就能滿足我們的需求。這里就用到了泛型的類型形參。

利用泛型改進一下 Sum 函數(shù)

// T:類型形參。調(diào)用 Sum 時,需指定 T 的類型值。

// [T int|int32|float32] 稱為類型形參列表。

// int|int32|float32 為類型約束,表示僅支持列出的類型。

func Sum[T int|int32|float32](x, y T) T{

return x + y

}

func main() {

fmt.Println(Sum[float32](1.1, 2.2)) // 顯示指定參數(shù)的類型

fmt.Println(Sum(1, 2)) // 隱式斷言

}

2. 泛型定義

// 自定義一個新類型 MapT

type MapT[T int|int32|string] map[T]string

上面代碼定義一個新類型 MapT,其中:

T:類型形參。定義 MapT 時 T 代表的類型并不確定,類似一個占位符。int|int32|string:類型約束。指定 T 僅可接受哪些類型。中括號內(nèi) T int|int32|string 定義形參類型,稱為形參類型列表。

其中,類型約束可以包上 interface{}

示例如下:

type Map[T interface{int|int32|string}] map[T]string

func MakeMap[T interface{int|int32|string}](key T, val string) Map[T] {

m := make(Map[T])

m[T] = val

return m

}

// 或簡寫為

type T interface{int|int32|float32|string} // 自定義類型約束

type MapT[t T] map[t]string // 可理解為泛型類型的聲明,后續(xù)聲明都使用 t 代替

// T 為類型約束;必須已定義,否則報錯。

// 返回值 MapT[t] 不可改為 Map[t],因兩者類型約束不同。

func MakeMapT[t T](key t, val string) MapT[t] {

m := make(MapT[])

m[T] = val

return m

}

不同類型使用泛型

type T interface{int|int32|float32|string|bool}

// 泛型類型切片

type SliceT [t T] []t

// 泛型類型結(jié)構(gòu)體

type StructT[t T] struct {

id int

data t

}

// 泛型類型結(jié)構(gòu)體方法

func (s *StructT[t]) SetData(v t) {

s.data = v

}

// 泛型類型 chan

type ChanT[t T] chan t

// 泛型類型接口

type Animal[t T] interface {

Running(t)

}

func main() {

// 下面代碼報錯。SliceT[T] 是泛型類型,不能直接使用 T,必須實例化具體的類型。

var i SliceT[T] = []int{1, 2, 3} // cannot use type T outside a type constraint: interface contains type constraints

// 正確使用

var s SliceT[string] = []string{"Hello", "World"}

fmt.Println(s)

// 結(jié)構(gòu)體方法

s := &StructT[float32]{

id: 1,

}

s.SetData(3.6)

fmt.Println(s)

}

4. ~ :指定底層類型

先看一個示例:

package main

import "fmt"

type T interface { int | int32 | int64 }

type Slice[t T] []t

type MyInt int

func main() {

var s = Slice[int]{1, 2, 3, 4, 5} // ok

fmt.Println(s)

// 泛型類型 Slice[T] 允許 int 作為類型實參;而 MyInt 與 int 屬于兩個類型。

var s2 = Slice[MyInt]{1, 2, 3, 4, 5} // 報錯,MyInt does not satisfy T (possibly missing ~ for int in T)

}

上述示例中,泛型類型 Slice[T] 允許 int 作為類型實參,而不是 MyInt。

雖然 MyInt 底層類型是 int,但它屬于自定義的一個底層為 int 的新類型,而不是 int 類型。

為解決上述問題,Go 新增了一個 ~ 符號;在類型約束中的類型前加 ~ 就表示以該類型為底層類型的類型都可以用于實例化。

把上述代碼中的類型約束 T 優(yōu)化一下就可以正常執(zhí)行。如下:

type T interface { ~int | ~int32 | ~int64 }

使用 ~ 的限制:

~ 后面的類型必須為基本類型。~ 后面類型不能為接口。

3. 類型約束

定義泛型類型時,基礎(chǔ)類型不能只有類型形參 type NewType[T int|float32] T // 報錯, cannot use a type parameter as RHS in type declaration

// 改寫一下

// 編譯沒問題。

// 雖然使用了類型形參,但類型定義未使用形參,底層類型為 int。

type NewType[T int|float32] int

func main() {

var i NewType[int] = 1 // ok,類型形參 int 滿足約束,且賦值滿足底層類型 int

fmt.Println(i) // 1

var f NewType[float32] = 2 // ok,類型形參 float32 滿足約束,且賦值滿足底層類型 int

fmt.Println(f) // 2

var f2 NewType[float32] = 1.2 // 報錯, 類型形參 float32 滿足約束,但實際賦值非 int

// cannot use a type parameter as RHS in type declarationcannot use 1.2

// (untyped float constant) as NewType[float32] value in variable declaration (truncated)

}

約束類型會被編譯器誤認為表達式 type NewType[T *int] []T //報錯, 指針類型會誤認為表達式 *

// 可在約束后加逗號(,)消除歧義

type NewType[T *int|*float32,] []T

// 把約束類型包在 interface{} 內(nèi)(推薦此方法)

type NewType[T interface { *int|*float32 }] []T

約束類型不可重復(fù) type Int interface {int | ~int} // 報錯,int 與 ~int 重復(fù)。

匿名函數(shù)、匿名結(jié)構(gòu)體不支持泛型

柚子快報邀請碼778899分享:Golang 泛型詳解

http://yzkb.51969.com/

參考閱讀

評論可見,查看隱藏內(nèi)容

本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點和立場。

轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。

本文鏈接:http://gantiao.com.cn/post/19310446.html

發(fā)布評論

您暫未設(shè)置收款碼

請在主題配置——文章設(shè)置里上傳

掃描二維碼手機訪問

文章目錄