關於Golang的泛型

泛型(Generic)是一種用來協助製作通用function、struct用的功能。在泛型還沒有支援之前,要製作通用的function、stuct,通常就只能在輸入、輸出的地方使用interface{}結構。而且這樣做需要很小心的檢查使用是的形態是否正確。

淺談Golang Generic 泛型

什麼是泛型?

泛型(Generic)是一種用來協助製作通用function、struct用的功能。 在泛型還沒有支援之前,要製作通用的function、stuct,通常就只能在輸入、輸出的地方使用interface{}結構。 而且這樣做需要很小心的檢查使用是的形態是否正確。

在function參數上使用泛型

在使用泛型之前,我們會使用interface{}來製作通用function

例如:

func Add(a, b interface{}) interface{}{
  switch a.type{
    case int:
      return a.(int) + b.(int)
    case float32:
      return a.(float32) + b.(float32)
    default:
      panic("not support type")
  }
}

但是這樣每次要增加新的可以接受的結構時,就再需要增加不少的檢查code。而在有了泛型以後,這段的檢查,就可以交由編譯器來處理了。 就可以變成以下這樣

func Add[T int|float32](a, b T) T{
  return a + b
}
//調用時如下
Add[float32](1.1, 2,2)

即使未來有需要再增加支援int64形態,也只需要在中括號中再加上即可。

func Add[T int|float32|int64](a, b T) T{
  return a + b
}

在struct上使用泛型

泛型也支援在struct上面使用。

以下的例子是在定義API回傳JSON格式時,不論什麼情況,都需要擁有Code, Params, Data這三個Field,而Data才是用來放置該API的回傳值。 但要做到這樣,等於每個module中,都要重新再定義一次,確實很惱人。

後來公司同事想到可以利用泛型,來定義出通用的回傳框架,只要使用這個struct,就可以產出有基本結構的struct出來。

type DataResponse[T any] struct{
  Code   string   `json:"code"`   
  Params []string `json:"params"` 
  Data   T        `json:"data"`   
}

這樣以後要定義回傳結構時,就不用每次重複定義Code和Params了

type User{
    Name   string
    Avatar string
}
type DataResponse[User] GetUserResponse

總結

泛型的使用情境,是用來製作通用struct、通用function時使用的。 例如:通用的回傳結構、通用的資料結構(如Stack)。 但對我個人而言,我很少用到它,因為目前工作上面,我都是在做應用層面的功能開發,而不是寫Library。大部分需要用抽象整合起來的地方,都是使用interface來抽的。 幾乎沒有機會遇到必須使用泛型的情況,所以我對於泛型的認知也只到這邊而已。

ref

comments powered by Disqus