亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Go語言泛型打造優(yōu)雅的切片工具庫

 更新時間:2025年02月06日 08:34:02   作者:gopher_looklook  
泛型是一種編程范式,允許開發(fā)者在編寫代碼時定義通用的類型參數(shù),而不是具體的類型,本文將使用泛型實現(xiàn)打造優(yōu)雅的切片工具庫,希望對大家有所幫助

什么是泛型

泛型是一種編程范式,允許開發(fā)者在編寫代碼時定義通用的類型參數(shù),而不是具體的類型。通過泛型,可以編寫出能夠處理多種數(shù)據(jù)類型的代碼,而無需為每種類型重復編寫相同的邏輯。例如,一個泛型函數(shù)可以同時處理整數(shù)、浮點數(shù)、字符串等多種類型的數(shù)據(jù)。

泛型解決了什么問題

在 Go 語言引入泛型之前,開發(fā)者在處理不同數(shù)據(jù)類型時,往往需要編寫重復的代碼。例如,實現(xiàn)一個排序算法,可能需要為整數(shù)、浮點數(shù)、字符串等分別編寫不同的版本。這種重復不僅增加了代碼量,也降低了代碼的可維護性。引入泛型后,可以通過定義一個通用的類型參數(shù),編寫一個通用的排序函數(shù),從而提高代碼的復用性和可維護性。

基于泛型的常見切片操作

博主結合自身在實際開發(fā)當中的經(jīng)驗,將利用Go泛型,封裝一些常見的切片操作。本篇博客所編寫的代碼,皆可直接集成到生產環(huán)境的公共代碼庫中。各位小伙伴可以根據(jù)自身項目的實際情況,將對你們項目有幫助的代碼遷移到自己的項目當中。

1.反轉切片(改變原切片)

func ReverseOriginalSlice[T any](s []T) {
    for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
       s[i], s[j] = s[j], s[i]
    }
}

2.反轉切片(不改變原切片)

func ReverseSlice[T any](s []T) []T {
    res := make([]T, len(s))
    copy(res, s)
    ReverseOriginalSlice(res) // 調用之前的ReverseOriginalSlice函數(shù)
    return res
}

3.切片分批

func BatchSlice[T any](s []T, size int) [][]T {
    var batchSlice [][]T
    // 遍歷切片,每次取 size 個元素
    for i := 0; i < len(s); i += size {
       end := i + size
       // 處理最后一批元素數(shù)量不足 size 的情況
       if end > len(s) {
          end = len(s)
       }
       // 將當前批次的元素添加到結果中
       batchSlice = append(batchSlice, s[i:end])
    }
    return batchSlice
}

4.合并切片

func MergeSlices[T any](slices ...[]T) []T {
    totalLength := 0
    for _, slice := range slices {
       totalLength += len(slice)
    }
    res := make([]T, 0, totalLength)
    for _, slice := range slices {
       ls := make([]T, len(slice))
       copy(ls, slice)
       res = append(res, ls...)
    }
    return res
}

5.切片去重

func UniqueSlice[T comparable](s []T) []T {
    seen := make(map[T]bool)
    res := make([]T, 0, len(s))
    for _, v := range s {
       if !seen[v] {
          // 如果元素未出現(xiàn)過,添加到結果切片中
          res = append(res, v)
          seen[v] = true
       }
    }
    return res
}

6.切片轉哈希表

func SliceToMap[T any, K comparable](s []T, keyFunc func(T) K) map[K]T {
    res := make(map[K]T)
    for _, v := range s {
       key := keyFunc(v)
       res[key] = v
    }
    return res
}

7.哈希表轉切片

func MapToSlice[K comparable, V any, T any](m map[K]V, extractor func(V) T) []T {
    res := make([]T, 0, len(m))
    for _, v := range m {
       res = append(res, extractor(v))
    }
    return res
}

8.獲取切片元素的某個字段

func GetListField[T any, V any](s []T, fieldFunc func(T) V) []V {
    res := make([]V, 0, len(s))
    for _, item := range s {
       res = append(res, fieldFunc(item))
    }
    return res
}

9.切片全部元素滿足條件判斷

func SliceMatchCondition[T any](s []T, condition func(T) bool) bool {
    for _, v := range s {
       if !condition(v) {
          return false
       }
    }
    return true
}

10.取切片交集

func Intersection[T comparable](slices ...[]T) []T {
    if len(slices) == 0 {
       return nil
    }

    // 使用 map 來存儲第一個切片中的元素
    intersectionMap := make(map[T]int)
    for _, v := range slices[0] {
       intersectionMap[v]++
    }

    // 遍歷后續(xù)切片,更新交集
    for _, slice := range slices[1:] {
       m := make(map[T]int)
       for _, v := range slice {
          if _, exists := intersectionMap[v]; exists {
             m[v]++
          }
       }
       intersectionMap = m
    }

    // 將交集的元素收集到結果切片中
    var res []T
    for k := range intersectionMap {
       res = append(res, k)
    }

    return res
}

11.取切片并集

func Union[T comparable](slices ...[]T) []T {
    elementMap := make(map[T]struct{})
    for _, slice := range slices {
       for _, v := range slice {
          elementMap[v] = struct{}{}
       }
    }

    var res []T
    for k := range elementMap {
       res = append(res, k)
    }

    return res
}

代碼合集

我將上述所有代碼集成到一個slices.go文件當中。如果各位小伙伴們的項目有需要,只需將以下代碼完整拷貝到你們項目的基礎代碼工具庫即可。

slices.go

package slices

// 反轉切片(改變原切片)
func ReverseOriginalSlice[T any](s []T) {
    for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
       s[i], s[j] = s[j], s[i]
    }
}

// 反鉆切片(不改變原切片)
func ReverseSlice[T any](s []T) []T {
    res := make([]T, len(s))
    copy(res, s)
    ReverseOriginalSlice(res)  
    return res
}

// 切片分批
func BatchSlice[T any](s []T, size int) [][]T {
    var batchSlice [][]T
    
    for i := 0; i < len(s); i += size {
       end := i + size
  
       if end > len(s) {
          end = len(s)
       }
       
       batchSlice = append(batchSlice, s[i:end])
    }
    return batchSlice
}

// 合并切片
func MergeSlices[T any](slices ...[]T) []T {
    totalLength := 0
    for _, slice := range slices {
       totalLength += len(slice)
    }
    res := make([]T, 0, totalLength)
    for _, slice := range slices {
       ls := make([]T, len(slice))
       copy(ls, slice)
       res = append(res, ls...)
    }
    return res
}

// 切片去重
func UniqueSlice[T comparable](s []T) []T {
    seen := make(map[T]bool)
    res := make([]T, 0, len(s))
    for _, v := range s {
       if !seen[v] {
          res = append(res, v)
          seen[v] = true
       }
    }
    return res
}

// 切片轉哈希表
func SliceToMap[T any, K comparable](s []T, keyFunc func(T) K) map[K]T {
    res := make(map[K]T)
    for _, v := range s {
       key := keyFunc(v)
       res[key] = v
    }
    return res
}

// 哈希表轉切片
func MapToSlice[K comparable, V any, T any](m map[K]V, extractor func(V) T) []T {
    res := make([]T, 0, len(m))
    for _, v := range m {
       res = append(res, extractor(v))
    }
    return res
}

// 獲取切片元素的某個字段
func GetListField[T any, V any](s []T, fieldFunc func(T) V) []V {
    res := make([]V, 0, len(s))
    for _, item := range s {
       res = append(res, fieldFunc(item))
    }
    return res
}

// 切片全部元素滿足條件判斷
func SliceMatchCondition[T any](s []T, condition func(T) bool) bool {
    for _, v := range s {
       if !condition(v) {
          return false
       }
    }
    return true
}

// 取切片交集
func Intersection[T comparable](slices ...[]T) []T {
    if len(slices) == 0 {
       return nil
    }

    intersectionMap := make(map[T]int)
    for _, v := range slices[0] {
       intersectionMap[v]++
    }

    for _, slice := range slices[1:] {
       m := make(map[T]int)
       for _, v := range slice {
          if _, exists := intersectionMap[v]; exists {
             m[v]++
          }
       }
       intersectionMap = m
    }

    var res []T
    for k := range intersectionMap {
       res = append(res, k)
    }

    return res
}

// 取切片并集
func Union[T comparable](slices ...[]T) []T {
    elementMap := make(map[T]struct{})
    for _, slice := range slices {
       for _, v := range slice {
          elementMap[v] = struct{}{}
       }
    }

    var res []T
    for k := range elementMap {
       res = append(res, k)
    }

    return res
}

總結

本文使用Go泛型,對常見的切片操作進行了封裝,整理出了一個切片工具庫slices.go。

到此這篇關于Go語言泛型打造優(yōu)雅的切片工具庫的文章就介紹到這了,更多相關Go泛型內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 詳解Go函數(shù)和方法之間有什么區(qū)別

    詳解Go函數(shù)和方法之間有什么區(qū)別

    這篇文章就簡單和大家聊一聊在Go中函數(shù)與方法之間的區(qū)別,文章通過代碼示例介紹的非常詳細,對我們的學習或工作有一定的幫助,感興趣的小伙伴跟著小編一起來看看吧
    2023-07-07
  • GO語言結構體面向對象操作示例

    GO語言結構體面向對象操作示例

    這篇文章主要介紹了GO語言編程中結構體面向對象的操作示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步早日升職加薪
    2022-04-04
  • Golang標準庫binary詳解

    Golang標準庫binary詳解

    這篇文章主要介紹了Golang標準庫binary的相關資料,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-05-05
  • Go實現(xiàn)自動解壓縮包以及讀取docx/doc文件內容詳解

    Go實現(xiàn)自動解壓縮包以及讀取docx/doc文件內容詳解

    在開發(fā)過程中,我們常常需要處理壓縮包和文檔文件。本文將介紹如何使用Go語言自動解壓縮包和讀取docx/doc文件,需要的可以參考一下
    2023-03-03
  • 如何使用Go檢測用戶本地是否安裝chrome

    如何使用Go檢測用戶本地是否安裝chrome

    這篇文章主要為大家詳細介紹了如何使用Go檢測用戶本地是否安裝chrome,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2024-10-10
  • 關于Golang標準庫flag的全面講解

    關于Golang標準庫flag的全面講解

    這篇文章主要介紹了關于Golang標準庫flag的全面講解,這個庫的代碼量只有1000行左右,卻提供了非常完善的命令行參數(shù)解析功能,更多相關內容需要的朋友可以參考一下
    2022-09-09
  • 深度解密 Go 語言中的 sync.Pool

    深度解密 Go 語言中的 sync.Pool

    sync.Pool 是 sync 包下的一個組件,可以作為保存臨時取還對象的一個“池子”。這篇文章主要介紹了深度解密 Go 語言中的sync.Pool,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-04-04
  • Golang高性能持久化解決方案BoltDB數(shù)據(jù)庫介紹

    Golang高性能持久化解決方案BoltDB數(shù)據(jù)庫介紹

    這篇文章主要為大家介紹了Golang高性能持久化解決方案BoltDB數(shù)據(jù)庫介紹,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步
    2021-11-11
  • Go中時間與時區(qū)問題的深入講解

    Go中時間與時區(qū)問題的深入講解

    go語言中如果不設置指定的時區(qū),通過time.Now()獲取到的就是本地時區(qū),下面這篇文章主要給大家介紹了關于Go中時間與時區(qū)問題的相關資料,需要的朋友可以參考下
    2021-12-12
  • golang 實現(xiàn)Location跳轉方式

    golang 實現(xiàn)Location跳轉方式

    這篇文章主要介紹了golang 實現(xiàn)Location跳轉方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-05-05

最新評論