最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

什么是泛型

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

泛型解決了什么問題

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

基于泛型的常見切片操作

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

1.反轉(zhuǎn)切片(改變原切片)

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.反轉(zhuǎn)切片(不改變原切片)

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

3.切片分批

func BatchSlice[T any](s []T, size int) [][]T {
    var batchSlice [][]T
    // 遍歷切片,每次取 size 個(gè)元素
    for i := 0; i < len(s); i += size {
       end := i + size
       // 處理最后一批元素?cái)?shù)量不足 size 的情況
       if end > len(s) {
          end = len(s)
       }
       // 將當(dāng)前批次的元素添加到結(jié)果中
       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)過,添加到結(jié)果切片中
          res = append(res, v)
          seen[v] = true
       }
    }
    return res
}

6.切片轉(zhuǎn)哈希表

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.哈希表轉(zhuǎn)切片

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.獲取切片元素的某個(gè)字段

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 來存儲(chǔ)第一個(gè)切片中的元素
    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
    }

    // 將交集的元素收集到結(jié)果切片中
    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
}

代碼合集

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

slices.go

package slices

// 反轉(zhuǎn)切片(改變原切片)
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
}

// 切片轉(zhuǎn)哈希表
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
}

// 哈希表轉(zhuǎn)切片
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
}

// 獲取切片元素的某個(gè)字段
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
}

總結(jié)

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

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

相關(guān)文章

  • Go實(shí)現(xiàn)一個(gè)輕量級(jí)并發(fā)任務(wù)調(diào)度器(支持限速)

    Go實(shí)現(xiàn)一個(gè)輕量級(jí)并發(fā)任務(wù)調(diào)度器(支持限速)

    本文主要介紹了Go實(shí)現(xiàn)一個(gè)輕量級(jí)并發(fā)任務(wù)調(diào)度器(支持限速),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-04-04
  • Go?Excelize?API源碼閱讀Close及NewSheet方法示例解析

    Go?Excelize?API源碼閱讀Close及NewSheet方法示例解析

    這篇文章主要為大家介紹了Go?Excelize?API源碼閱讀Close及NewSheet方法示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • Golang實(shí)現(xiàn)密碼加密的示例詳解

    Golang實(shí)現(xiàn)密碼加密的示例詳解

    數(shù)據(jù)庫在存儲(chǔ)密碼時(shí),不能明文存儲(chǔ),需要加密后存儲(chǔ),而Golang中的加密算法有很多種,下面小編就來通過簡單的示例和大家簡單聊聊吧
    2023-07-07
  • golang實(shí)現(xiàn)循環(huán)隊(duì)列的示例代碼

    golang實(shí)現(xiàn)循環(huán)隊(duì)列的示例代碼

    循環(huán)隊(duì)列是一種使用固定大小的數(shù)組來實(shí)現(xiàn)隊(duì)列的數(shù)據(jù)結(jié)構(gòu),本文主要介紹了golang實(shí)現(xiàn)循環(huán)隊(duì)列的示例代碼,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-07-07
  • 在go文件服務(wù)器加入http.StripPrefix的用途介紹

    在go文件服務(wù)器加入http.StripPrefix的用途介紹

    這篇文章主要介紹了在go文件服務(wù)器加入http.StripPrefix的用途介紹,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • Golang 類型斷言的具體使用

    Golang 類型斷言的具體使用

    本文主要介紹了Golang 類型斷言的具體使用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • go new和make的區(qū)別以及為什么new返回的是指針問題分析

    go new和make的區(qū)別以及為什么new返回的是指針問題分析

    Go語言中new和make的區(qū)別在于:new用于分配值類型內(nèi)存并返回指針,適用于所有值類型;make用于創(chuàng)建并初始化slice、map和channel,只適用于引用類型,new返回指針可以明確表示值是在堆上分配的,避免不必要的值拷貝,并且與零值初始化語義一致
    2026-01-01
  • Golang實(shí)現(xiàn)自己的Redis(pipeline客戶端)實(shí)例探索

    Golang實(shí)現(xiàn)自己的Redis(pipeline客戶端)實(shí)例探索

    這篇文章主要為大家介紹了Golang實(shí)現(xiàn)自己的Redis(pipeline客戶端)實(shí)例探索,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-01-01
  • Golang?Compare?And?Swap算法詳細(xì)介紹

    Golang?Compare?And?Swap算法詳細(xì)介紹

    CAS算法是一種有名的無鎖算法。無鎖編程,即不使用鎖的情況下實(shí)現(xiàn)多線程之間的變量同步,也就是在沒有線程被阻塞的情況下實(shí)現(xiàn)變量的同步,所以也叫非阻塞同步Non-blocking?Synchronization
    2022-10-10
  • 詳解如何在Go中如何編寫出可測試的代碼

    詳解如何在Go中如何編寫出可測試的代碼

    在編寫測試代碼之前,還有一個(gè)很重要的點(diǎn),容易被忽略,就是什么樣的代碼是可測試的代碼,所以本文就來聊一聊在?Go?中如何寫出可測試的代碼吧
    2023-08-08

最新評(píng)論

澜沧| 报价| 芒康县| 鄂托克前旗| 安义县| 堆龙德庆县| 余姚市| 西林县| 朝阳区| 滁州市| 乐平市| 六盘水市| 黑龙江省| 太湖县| 太仓市| 乐昌市| 灵宝市| 象山县| 呼伦贝尔市| 鄂温| 印江| 阿拉善左旗| 丽水市| 和龙市| 遵义市| 双鸭山市| 灵山县| 阿荣旗| 永安市| 遵义市| 鸡西市| 罗源县| 寻乌县| 南开区| 南郑县| 军事| 徐汇区| 扎兰屯市| 大悟县| 湖北省| 获嘉县|