搜尋
首頁後端開發GolangGo 中的泛型:改變程式碼可重複使用性

Go 1.18 中引入的泛型徹底改變了編寫可重複使用和類型安全程式碼的方式。泛型帶來了靈活性和強大的功能,同時保持了 Go 的簡單哲學。然而,要了解細微差別、優點以及泛型與傳統方法(如 interface{} )的比較,需要仔細觀察。

讓我們探索泛型的複雜性,深入研究約束,將泛型與介面{}進行比較,並示範它們的實際應用。我們還將討論性能考慮因素和二進制大小的影響。讓我們開始吧!

什麼是泛型?

泛型允許開發人員編寫可以在任何類型上操作的函數和資料結構,同時保持類型安全。泛型不依賴涉及執行時間類型斷言的介面{},而是讓您指定一組約束來規定類型上允許的操作。

文法

func FunctionName[T TypeConstraint](parameterName T) ReturnType {
    // Function body using T
}

T: 型態參數,表示型別的佔位符。

TypeConstraint:將 T 的類型限制為特定類型或一組類型。

parameterName T:參數使用泛型類型T.

ReturnType:函數也可以傳回 T.

類型的值

範例

func Sum[T int | float64](a, b T) T {
    return a + b
}

func Sum: 宣告函數名稱 Su​​m

[T int | float64]: 指定引入T 作為類型參數的類型參數列表,約束為特定類型(int 或float64 )。 Sum 函數只能採用 int 或 float64 參數,不能組合使用,兩者都必須是 intfloat64。我們將在下面的部分中進一步探討這一點。

(a, b T): 宣告兩個參數a 和b,皆為T 類型(泛型型別) ).

T: 指定函數的回傳類型,與型別參數 T.

相符

約束:泛型的建構塊

約束定義哪些操作對於泛型類型有效。 Go 提供了強大的約束工具,包括實驗性約束套件(golang.org/x/exp/constraints)。

內建約束

Go 引入了具有泛型的內建約束,以提供類型安全,同時允許靈活地定義可重複使用和泛型程式碼。這些約束使開發人員能夠對泛型函數或類型中使用的類型強制執行規則。

Go 有以下內建約束

  1. any:代表任意型別。它是 interface{} 的別名。當不需要約束時使用
func FunctionName[T TypeConstraint](parameterName T) ReturnType {
    // Function body using T
}
  1. comparable:允許支援相等比較(== 和 !=)的型別。對於映射鍵、重複檢測或相等檢查很有用。這不能用於映射、切片和函數,因為這些類型不支援直接比較。
func Sum[T int | float64](a, b T) T {
    return a + b
}

實驗限制

  1. constraints.Complex:允許複雜數字類型(complex64 和complex128)。
  2. constraints.Float:允許浮點數值型別(float32 和 float64)
  3. constraints.Integer:允許任何有符號和無符號整數(int8、int16、int32、int64、int、uint8、uint16、uint32、uint64 和 uint)
  4. constraints.Signed:允許任何有符號整數(int8、int16、int32、int64 和 int)
  5. constraints.Unsigned:允許任何無符號整數(uint8、uint16、uint32、uint64 和 uint)。
  6. constraint.Ordered:允許進行比較的類型(<.>、>=),支援所有數字類型和字串(int、float64、string 等)。
func PrintValues[T any](values []T) {
    for _, v := range values {
        fmt.Println(v)
    }
}

自訂約束

自訂限制是定義泛型類型參數必須滿足的一組類型或類型行為的介面。透過創建您自己的約束,我們可以;

  • 將類型限制為特定子集,例如數字類型。

  • 需要型別來實作特定的方法或行為。

  • 為您的通用函數和類型添加更多控制和特異性。

文法

func CheckDuplicates[T comparable](items []T) []T {
    seen := make(map[T]bool)
    duplicates := []T{}
    for _, item := range items {
        if seen[item] {
            duplicates = append(duplicates, item)
        } else {
            seen[item] = true
        }
    }
    return duplicates
}

範例

import (
     "golang.org/x/exp/constraints"
     "fmt"
)

func SortSlice[T constraints.Ordered](items []T) []T {
    sorted := append([]T{}, items...) // Copy slice
    sort.Slice(sorted, func(i, j int) bool {
        return sorted[i] 


<p><strong><em>Sum 函數</em></strong> 只能使用 int、int64 和 float64 參數呼叫。 </p>
<h3>
  
  
  方法的限制
</h3>

<p>如果你想強制型別必須實作某些方法,你可以使用這些方法來定義它。 <br>
</p>
<pre class="brush:php;toolbar:false">type Numeric interface {
    int | float64 | uint
}

Formatter 約束要求任何用作T 的類型必須具有傳回字串.

組合約束

自訂限制可以結合型別集與方法要求


type Number interface {
    int | int64 | float64
}

func Sum[T Number](a, b T) T {
    return a + b
}
此限制包括兩種特定類型(

int、float54),並且需要有 abs 方法。

泛型與介面{}

在引入泛型之前,使用interface{}來實現靈活性。然而,這種方法有其限制。

類型安全

  • interface{}:依賴執行階段類型斷言,增加執行時間出錯的幾率。

  • 泛型:提供編譯時類型安全性,在開發過程中儘早捕捉錯誤。

表現

  • 介面{}:由於額外的執行時間類型檢查,速度較慢。

  • 泛型:更快,因為編譯器會產生特定於類型的最佳化程式碼路徑。

程式碼可讀性

  • 介面{}:通常冗長且不太直觀,使程式碼更難維護。

  • 泛型:更簡潔的語法可以帶來更直覺和可維護的程式碼。

二進位大小

  • interface{}:產生更小的二進位文件,因為它不會為不同類型重複程式碼。

  • 泛型:由於類型專門化而略微增加二進位大小以獲得更好的性能。

範例

func FunctionName[T TypeConstraint](parameterName T) ReturnType {
    // Function body using T
}

程式碼運作良好,型別斷言是開銷。 Add 函數可以使用任何參數調用,a 和 b 參數可以是不同的類型,但是程式碼會在運行時崩潰。

func Sum[T int | float64](a, b T) T {
    return a + b
}

泛型消除了由不正確的類型斷言引起的運行時恐慌的風險並提高了清晰度。

表現

泛型為每種類型產生專門的程式碼,與介面{}相比,可以帶來更好的執行時間效能。

二進位大小

存在一個權衡:泛型由於每種類型的程式碼重複而增加了二進位大小,但這與好處相比通常可以忽略不計。

Go 泛型的局限性

約束的複雜性: 雖然像 Constraints.Ordered 這樣的限制簡化了常見用例,但定義高度自訂的約束可能會變得冗長。

結構體中沒有類型推論: 與函數不同,您必須為結構體明確指定類型參數。

func PrintValues[T any](values []T) {
    for _, v := range values {
        fmt.Println(v)
    }
}

僅限於編譯時約束:Go 泛型專注於編譯時安全,而 Rust 這樣的語言使用生命週期和特徵提供更強大的限制。

讓我們進行基準測試——做得比說的更好

我們將實作一個具有介面{}和通用的簡單佇列,並對結果進行基準測試。

介面{}隊列實現

func CheckDuplicates[T comparable](items []T) []T {
    seen := make(map[T]bool)
    duplicates := []T{}
    for _, item := range items {
        if seen[item] {
            duplicates = append(duplicates, item)
        } else {
            seen[item] = true
        }
    }
    return duplicates
}

通用佇列實現

import (
     "golang.org/x/exp/constraints"
     "fmt"
)

func SortSlice[T constraints.Ordered](items []T) []T {
    sorted := append([]T{}, items...) // Copy slice
    sort.Slice(sorted, func(i, j int) bool {
        return sorted[i] 



<pre class="brush:php;toolbar:false">type Numeric interface {
    int | float64 | uint
}

結果分析

  • 執行時間:
    通用實作比 interface{} 版本快約 63.64%,因為它避免了運行時類型斷言並直接對給定類型進行操作。

  • 分配:
    Interface{} 版本的分配量增加了 3 倍,這主要是由於插入和檢索值時的裝箱/拆箱。這增加了垃圾收集的開銷。

對於較大的工作負載,例如 100 萬次入隊/出隊操作,效能差距會擴大。具有高吞吐量要求的實際應用程式(例如訊息佇列、作業排程器)可以從泛型中受益匪淺。

最後的想法

Go 中的泛型在功能強大和簡單性之間取得了平衡,為編寫可重複使用和類型安全的程式碼提供了實用的解決方案。雖然不像 Rust 或 C 那樣功能豐富,但與 Go 的極簡主義哲學完美契合。了解約束等約束。有效有序和利用泛型可以大幅提高程式碼品質和可維護性。

隨著泛型的不斷發展,它們注定會在 Go 的生態系統中發揮核心作用。因此,潛入、實驗並擁抱 Go 程式設計類型安全性和靈活性的新時代!

查看 github 儲存庫以取得一些關於泛型的範例。

GitHub logo 薩達南多達瓦達卡爾 / Go泛型

儲存庫包含 go 泛型的工作範例

Go 泛型:綜合範例儲存庫

歡迎來到Go 泛型儲存庫!此儲存庫是 1.18 版本中引入的用於理解、學習和掌握 Go 中泛型的一站式資源。泛型為 Go 帶來了類型參數的強大功能,使開發人員能夠編寫可重複使用且類型安全的程式碼,而不會影響效能或可讀性。

該儲存庫包含精心策劃的範例,涵蓋廣泛的主題,從基本語法到高級模式和實際用例。無論您是初學者還是經驗豐富的 Go 開發人員,此集合都將幫助您在專案中有效地利用泛型。


?裡面有什麼

?基本通用程式

這些範例介紹了泛型的基本概念,幫助您掌握文法和核心功能:

  1. GenericMap:示範通用映射函數來轉換任何類型的切片。
  2. 交換:一般交換兩個值的簡單而強大的範例。
  3. FilterSlice:顯示如何過濾...


在 GitHub 上查看


以上是Go 中的泛型:改變程式碼可重複使用性的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
進行錯誤處理:最佳實踐和模式進行錯誤處理:最佳實踐和模式May 04, 2025 am 12:19 AM

在Go編程中,有效管理錯誤的方法包括:1)使用錯誤值而非異常,2)採用錯誤包裝技術,3)定義自定義錯誤類型,4)復用錯誤值以提高性能,5)謹慎使用panic和recover,6)確保錯誤消息清晰且一致,7)記錄錯誤處理策略,8)將錯誤視為一等公民,9)使用錯誤通道處理異步錯誤。這些做法和模式有助於編寫更健壯、可維護和高效的代碼。

您如何在GO中實施並發?您如何在GO中實施並發?May 04, 2025 am 12:13 AM

在Go中實現並發可以通過使用goroutines和channels來實現。 1)使用goroutines來並行執行任務,如示例中同時享受音樂和觀察朋友。 2)通過channels在goroutines之間安全傳遞數據,如生產者和消費者模式。 3)避免過度使用goroutines和死鎖,合理設計系統以優化並發程序。

在GO中構建並發數據結構在GO中構建並發數據結構May 04, 2025 am 12:09 AM

Gooffersmultipleapproachesforbuildingconcurrentdatastructures,includingmutexes,channels,andatomicoperations.1)Mutexesprovidesimplethreadsafetybutcancauseperformancebottlenecks.2)Channelsofferscalabilitybutmayblockiffullorempty.3)Atomicoperationsareef

將GO的錯誤處理與其他編程語言進行比較將GO的錯誤處理與其他編程語言進行比較May 04, 2025 am 12:09 AM

go'serrorhandlingisexplicit,治療eRROSASRETRATERTHANEXCEPTIONS,與pythonandjava.1)go'sapphifeensuresererrawaresserrorawarenessbutcanleadtoverbosecode.2)pythonandjavauseexeexceptionseforforforforforcleanerCodebutmaymobisserrors.3)

測試代碼依賴於INET功能的代碼測試代碼依賴於INET功能的代碼May 03, 2025 am 12:20 AM

whentestinggocodewithinitfunctions,useexplicitseTupfunctionsorseParateTestFileSteSteTepteTementDippedDependendendencyOnInItfunctionsIdeFunctionSideFunctionsEffect.1)useexplicitsetupfunctionStocontrolglobalvaribalization.2)createSepEpontrolglobalvarialization

將GO的錯誤處理方法與其他語言進行比較將GO的錯誤處理方法與其他語言進行比較May 03, 2025 am 12:20 AM

go'serrorhandlingurturnserrorsasvalues,與Javaandpythonwhichuseexceptions.1)go'smethodensursexplitirorhanderling,propertingrobustcodebutincreasingverbosity.2)

設計有效界面的最佳實踐設計有效界面的最佳實踐May 03, 2025 am 12:18 AM

AnefactiveInterfaceingoisminimal,clear and promotesloosecoupling.1)minimizeTheInterfaceForflexibility andeaseofimplementation.2)useInterInterfaceForabStractionToswaPimplementations withoutchangingCallingCode.3)

集中式錯誤處理策略集中式錯誤處理策略May 03, 2025 am 12:17 AM

集中式錯誤處理在Go語言中可以提升代碼的可讀性和可維護性。其實現方式和優勢包括:1.將錯誤處理邏輯從業務邏輯中分離,簡化代碼。 2.通過集中處理錯誤,確保錯誤處理的一致性。 3.使用defer和recover來捕獲和處理panic,增強程序健壯性。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

將Eclipse與SAP NetWeaver應用伺服器整合。

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器