Go 快速指南:go1.18 特性

cuua發表於2021-12-14

即將在 2022 年第一季釋出的 Go 1.18 版本,有很多新特性正等著我們。

這個版本將是 Go 歷史版本裡最關鍵的版本之一,我們將在一個月內嚐鮮到 beta 版。到底有哪些更新呢?

引數型別(泛型)

Go 期待已久的引數型別特性,也就是其他語言裡的泛型。有了這個特性,我們可以給函式傳遞動態型別。讓我們深入到一個簡單的例子,通過編寫一個函式來查詢任意兩個 int 變數中的最小值

func minInt(x int, y int) int {
   if x < y {
      return x
   } else {
      return y
   }
}

當我們需要為 float32 變數提供相同功能時,我們需要重新寫一個類似的函式

func minFloat(x float32, y float32) float32 {
   if x < y {
      return x
   } else {
      return y
   }
}

通過泛型的能力,我們可以輕鬆的定義一個函式,這樣我們可以得到所需型別的變數。通過定義型別,我們還可以看到一個名為~的新操作符。這個操作符實際上返回給我們的是型別資訊的介面,因此我們可以進行型別限制,讓我們來編寫相同的 min 函式來包含 int 和 float32,如下所示:

type OrderTypes interface { 
   ~int | ~float32 
}
func min[P OrderTypes](x, y P) P {
    if x < y {
      return x
    } else {
      return y
    }
}

這看起來很可靠 ,對吧。Go 還建議使用已經定義型別組的約束庫。例如,我們可以為所有有序型別實現我們的函式。

func min[P constraints.Ordered](x, y P) P {
    if x < y {
      return x
    } else {
      return y
    }
}

當然,泛型的使用不僅僅限於這個例子。它會非常有用,尤其 ORM-style 型別的問題中,在那種我們建立需要處理多個型別引數的函式。同時,你還可以跟著過一下 GO 團隊分享的例子,從中得到一些想法。

除此之外,我們可以進行實驗的線上編輯(playground)也很有用。如果你希望使用 1.18 在你自己的環境,你可以下載 gotip 並使用 Go 的活躍的分支。

模糊測試

隨著 Go1.18 軟體包的釋出,"模糊化"功能將進入我們的生活。有了這個在 beta 版提供的測試庫,我們將能夠在單元測試中自動做隨機突變輸入。

作為軟體開發者,我們有時會忘了單元測試的邊緣案例。特別在重要的庫上,這種缺少資料的多樣性可能會被濫用,也會導致安全洩漏和漏洞。我們可以通過模糊測試來預防這種情況。

為了實現模糊測試,你可以使用以模糊字首開頭的方法包裝單元測試。你還可以使用 Go 的測試頁作為示例程式碼。

func FuzzHex(f *testing.F) {
  for _, seed := range [][]byte{{}, {0}, {9}, {0xa}, {0xf}, {1, 2, 3, 4}} {
    f.Add(seed)
  }
  f.Fuzz(func(t *testing.T, in []byte) {
    enc := hex.EncodeToString(in)
    out, err := hex.DecodeString(enc)
    if err != nil {
      t.Fatalf("%v: decode: %v", in, err)
    }
    if !bytes.Equal(in, out) {
      t.Fatalf("%v: not equal after round trip: %v", in, out)
    }
  })
}

工作區

此功能提升了同時需要處理多個模組的開發人員的便利性。儘管可以在 go.mod 1.17 版本中使用 replace 命令更改 module 版本。但是在提交程式碼的時候,常常忘記清除這些 replace 命令。對於我們開發人員來說,每次插入或刪除該行都是一件非常麻煩的事情。

使用工作區功能,你可以建立一個名為 go.work 的新檔案,在那裡編寫 replace 命令。此檔案允許我們更改特定工作環境的 modules 且無需更改已有的 go.mod 檔案。例如,你可以檢視 property 提出的設計頁面

go 1.17

directory (
    ./baz // foo.org/bar/baz
    ./tools // golang.org/x/tools
)

replace golang.org/x/net => example.com/fork/net v1.4.5

綜上,Go1.18 提供了有用的模糊化和工作區特性,以及討論、研究超過一年的泛型特性。除此之外,此版本還提供許多改進和修復,您可以通過此連結 瞭解版本的狀態及其包含的內容。

更多原創文章乾貨分享,請關注公眾號
  • Go 快速指南:go1.18 特性
  • 加微信實戰群請加微信(註明:實戰群):gocnio

相關文章