天天看點

一文搞懂Go1.18泛型新特性

關于Go1.18版本的釋出,當然不隻有泛型(Generics)這一個新特性,具體的釋出文檔可以看下Go官方部落格:https://go.dev/blog/go1.18,可以看出除了泛型,還增加了工作區、模糊測試等新特性,但是泛型這一特性無疑是最引人矚目的,再貼一下泛型學習的官方文檔:https://go.dev/doc/tutorial/generics,接下來就跟随官方文檔還有此篇部落格,一起來搞懂Go1.18新特性—泛型!

1 安裝Go1.18和環境

下載下傳位址:

​​https://go.dev/dl/go1.18.3.windows-amd64.msi​​

​​https://go.dev/dl/go1.18.3.darwin-amd64.pkg​​

​​https://go.dev/dl/go1.18.3.linux-amd64.tar.gz​​

IDE的話目前GoLand2022.1版本以上才支援泛型程式設計,VSCode、Vim也可以,但是個人比較喜歡使用GoLand

2 Go泛型程式設計執行個體

2.1 泛型容器

泛型List

type MyList[T any] struct {
   Items []Item[T]
}

type Item[T any] struct {
   Index int
   Value T
}

func (list *MyList[T]) AddItem(i T) {
   item := Item[T]{Value: i, Index: len(list.Items)}
   list.Items = append(list.Items, item)
}

func (list *MyList[T]) GetItem(index int) T {
   l := list.Items
   var val T
   for i := range l {
      if l[i].Index == index {
         val = l[i].Value
      }
   }
   return val
}

func (list *MyList[T]) Print() {
   for i := range list.Items {
      fmt.Println(list.Items[i])
   }
}      

泛型Map

type MyHashMap[K comparable, V any] struct {
   Value map[K]V
}

func (m *MyHashMap[K, V]) SetValue(k K, v V) {
   m.Value[k] = v
}

func (m *MyHashMap[K, V]) GetValue(k K) V {
   return m.Value[k]
}

func (m *MyHashMap[K, V]) Print() {
   for k := range m.Value {
      fmt.Println(k, m.Value[k])
   }
}      

使用:

func main() {
   list := MyList[int]{}
   list.AddItem(1)
   list.AddItem(2)
   fmt.Println(list)
   item := list.GetItem(7)
   fmt.Println(item)
   list.Print()
   hashMap := MyHashMap[string, int]{map[string]int{"A": 1, "B": 2}}
   hashMap.SetValue("s", 2)
   fmt.Println(hashMap)
   value := hashMap.GetValue("s")
   fmt.Println(value)
   hashMap.Print()
}      
PS:
  • comparable:The comparable interface may only be used as a type parameter constraint, not as the type of a variable.(Comparable是由所有可比類型實作的接口 ,Comparable接口隻能用作類型參數限制,而不能用作變量的類型。 )
  • any:any is an alias for interface{} and is equivalent to interface{} in all ways.(Any是interface{}的别名,在所有方面等價于interface{}。 )

2.2 泛型類型

泛型類型和方法:

type Score interface {
   int64|float64 //限制類型
}

func GetNum[T Score](n1, n2 T) T {
   return n1 + n2
}      

使用:

func main() {
   num := GetNum[64](12.123,2)
   fmt.Println(num)
}      

3 小結

繼續閱讀