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

Go語(yǔ)言利用泛型封裝常見(jiàn)的Map操作

 更新時(shí)間:2025年02月07日 15:47:00   作者:gopher_looklook  
Go?語(yǔ)言在?1.18?版本中引入了泛型,這是?Go?語(yǔ)言發(fā)展的一個(gè)重要里程碑,它極大地增強(qiáng)了語(yǔ)言的表達(dá)能力和靈活性,本文將通過(guò)泛型實(shí)現(xiàn)封裝常見(jiàn)的Map操作,感興趣的可以了解下

什么是泛型

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

泛型解決了什么問(wèn)題

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

Go泛型

Go 語(yǔ)言在 1.18 版本中引入了泛型,這是 Go 語(yǔ)言發(fā)展的一個(gè)重要里程碑,它極大地增強(qiáng)了語(yǔ)言的表達(dá)能力和靈活性。

基于泛型的常見(jiàn)Map操作

在上一篇文章里,我們使用Go泛型打造了一個(gè)優(yōu)雅的切片工具庫(kù),本篇博客將利用Go泛型,封裝常見(jiàn)的Map操作,并配套相應(yīng)的單元測(cè)試。本篇博客所編寫的代碼,皆可直接集成到生產(chǎn)環(huán)境的公共代碼庫(kù)中。各位小伙伴可以根據(jù)自身項(xiàng)目的實(shí)際情況,將對(duì)你們項(xiàng)目有幫助的代碼遷移到自己的項(xiàng)目當(dāng)中。

1.獲取map的所有keys

func GetMapKeys[K comparable, V any](m map[K]V) []K {
    keys := make([]K, 0, len(m))
    for k := range m {
       keys = append(keys, k)
    }
    return keys
}

2.根據(jù)過(guò)濾條件獲取map的keys

func GetMapKeysMatchCondition[K comparable, V any](m map[K]V, condition func(K, V) bool) []K {
    keys := make([]K, 0, len(m))
    for k, v := range m {
       if condition(k, v) {
          keys = append(keys, k)
       }
    }
    return keys
}

3.獲取map的所有values

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

4.根據(jù)過(guò)濾條件獲取map的values

func GetMapValuesMatchCondition[K comparable, V any](m map[K]V, condition func(K, V) bool) []V {
    values := make([]V, 0, len(m))
    for k, v := range m {
       if condition(k, v) {
          values = append(values, v)
       }
    }
    return values
}

5.合并多個(gè)map

func MergeMaps[K comparable, V any](maps ...map[K]V) map[K]V {
    mergeMap := make(map[K]V)
    for _, m := range maps {
       for k, v := range m {
          mergeMap[k] = v
       }
    }
    return mergeMap
}

6.map轉(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
}

7.切片轉(zhuǎn)map

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
}

8.復(fù)制map

func CopyMap[K comparable, V any](oldMap map[K]V) map[K]V {
    newMap := make(map[K]V, len(oldMap))
    for k, v := range oldMap {
       newMap[k] = v
    }
    return newMap
}

9.sync.Map轉(zhuǎn)map

func SyncMapToMap[K comparable, V any](syncMap sync.Map) map[K]V {
    m := make(map[K]V)
    syncMap.Range(func(key, value any) bool {
       // 嘗試將key和value轉(zhuǎn)換為指定的類型
       k, ok1 := key.(K)
       v, ok2 := value.(V)
       if ok1 && ok2 {
          m[k] = v
       }
       return true
    })
    return m
}

10.map轉(zhuǎn)sync.Map

func MapToSyncMap[K comparable, V any](m map[K]V) *sync.Map {
    syncMap := &sync.Map{}
    if m == nil {
       return syncMap
    }
    for k, v := range m {
       syncMap.Store(k, v)
    }
    return syncMap
}

代碼合集

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

maps.go

package maps

import (
    "sync"
)

// 獲取map的所有keys
func GetMapKeys[K comparable, V any](m map[K]V) []K {
    keys := make([]K, 0, len(m))
    for k := range m {
       keys = append(keys, k)
    }
    return keys
}

// 根據(jù)過(guò)濾條件獲取map的keys
func GetMapKeysMatchCondition[K comparable, V any](m map[K]V, condition func(K, V) bool) []K {
    keys := make([]K, 0, len(m))
    for k, v := range m {
       if condition(k, v) {
          keys = append(keys, k)
       }
    }
    return keys
}

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

// 根據(jù)過(guò)濾條件獲取map的values
func GetMapValuesMatchCondition[K comparable, V any](m map[K]V, condition func(K, V) bool) []V {
    values := make([]V, 0, len(m))
    for k, v := range m {
       if condition(k, v) {
          values = append(values, v)
       }
    }
    return values
}

// 合并多個(gè)map
func MergeMaps[K comparable, V any](maps ...map[K]V) map[K]V {
    mergeMap := make(map[K]V)
    for _, m := range maps {
       for k, v := range m {
          mergeMap[k] = v
       }
    }
    return mergeMap
}

// map轉(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
}

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

// 復(fù)制map
func CopyMap[K comparable, V any](oldMap map[K]V) map[K]V {
    newMap := make(map[K]V, len(oldMap))
    for k, v := range oldMap {
       newMap[k] = v
    }
    return newMap
}

// sync.Map轉(zhuǎn)map
func SyncMapToMap[K comparable, V any](syncMap sync.Map) map[K]V {
    m := make(map[K]V)
    syncMap.Range(func(key, value any) bool {
       // 嘗試將key和value轉(zhuǎn)換為指定的類型
       k, ok1 := key.(K)
       v, ok2 := value.(V)
       if ok1 && ok2 {
          m[k] = v
       }
       return true
    })
    return m
}

func MapToSyncMap[K comparable, V any](m map[K]V) *sync.Map {
    syncMap := &sync.Map{}
    if m == nil {
       return syncMap
    }
    for k, v := range m {
       syncMap.Store(k, v)
    }
    return syncMap
}

maps_test.go

package maps

import (
    "sync"
    "testing"
)

// 測(cè)試 GetMapKeys 函數(shù)
func TestGetMapKeys(t *testing.T) {
    m := map[string]int{
       "apple":  1,
       "banana": 2,
       "cherry": 3,
    }
    keys := GetMapKeys(m)
    if len(keys) != len(m) {
       t.Errorf("Expected %d keys, got %d", len(m), len(keys))
    }
    for _, k := range keys {
       if _, exists := m[k]; !exists {
          t.Errorf("Key %s not found in original map", k)
       }
    }
}

// 測(cè)試 GetMapKeysMatchCondition 函數(shù)
func TestGetMapKeysMatchCondition(t *testing.T) {
    m := map[string]int{
       "apple":  1,
       "banana": 2,
       "cherry": 3,
    }
    condition := func(k string, v int) bool {
       return v > 1
    }
    keys := GetMapKeysMatchCondition(m, condition)
    for _, k := range keys {
       if m[k] <= 1 {
          t.Errorf("Key %s should not be included as its value is not greater than 1", k)
       }
    }
}

// 測(cè)試 GetMapValues 函數(shù)
func TestGetMapValues(t *testing.T) {
    m := map[string]int{
       "apple":  1,
       "banana": 2,
       "cherry": 3,
    }
    values := GetMapValues(m)
    if len(values) != len(m) {
       t.Errorf("Expected %d values, got %d", len(m), len(values))
    }
    valueSet := make(map[int]bool)
    for _, v := range values {
       valueSet[v] = true
    }
    for _, v := range m {
       if !valueSet[v] {
          t.Errorf("Value %d not found in result values", v)
       }
    }
}

// 測(cè)試 GetMapValuesMatchCondition 函數(shù)
func TestGetMapValuesMatchCondition(t *testing.T) {
    m := map[string]int{
       "apple":  1,
       "banana": 2,
       "cherry": 3,
    }
    condition := func(k string, v int) bool {
       return v > 1
    }
    values := GetMapValuesMatchCondition(m, condition)
    for _, v := range values {
       if v <= 1 {
          t.Errorf("Value %d should not be included as it is not greater than 1", v)
       }
    }
}

// 測(cè)試 MergeMaps 函數(shù)
func TestMergeMaps(t *testing.T) {
    m1 := map[string]int{
       "apple":  1,
       "banana": 2,
    }
    m2 := map[string]int{
       "banana": 3,
       "cherry": 4,
    }
    merged := MergeMaps(m1, m2)
    for k := range m1 {
       if _, exists := merged[k]; !exists {
          t.Errorf("key %s not exist in m1", k)
       }
    }
    for k := range m2 {
       if _, exists := merged[k]; !exists {
          t.Errorf("key %s not exist in m2", k)
       }
    }
}

// 測(cè)試 MapToSlice 函數(shù)
func TestMapToSlice(t *testing.T) {
    m := map[string]int{
       "apple":  1,
       "banana": 2,
       "cherry": 3,
    }
    extractor := func(v int) int {
       return v * 2
    }
    slice := MapToSlice(m, extractor)
    if len(slice) != len(m) {
       t.Errorf("Expected %d elements in slice, got %d", len(m), len(slice))
    }
    for _, v := range m {
       found := false
       for _, s := range slice {
          if s == v*2 {
             found = true
             break
          }
       }
       if !found {
          t.Errorf("Transformed value %d not found in slice", v*2)
       }
    }
}

// 測(cè)試 SliceToMap 函數(shù)
func TestSliceToMap(t *testing.T) {
    s := []int{1, 2, 3}
    keyFunc := func(v int) int {
       return v * 10
    }
    m := SliceToMap(s, keyFunc)
    if len(m) != len(s) {
       t.Errorf("Expected %d keys in map, got %d", len(s), len(m))
    }
    for _, v := range s {
       key := keyFunc(v)
       if val, exists := m[key]; !exists || val != v {
          t.Errorf("Value for key %d in map does not match original slice", key)
       }
    }
}

// 測(cè)試 CopyMap 函數(shù)
func TestCopyMap(t *testing.T) {
    oldMap := map[string]int{
       "apple":  1,
       "banana": 2,
       "cherry": 3,
    }
    newMap := CopyMap(oldMap)
    if len(newMap) != len(oldMap) {
       t.Errorf("Expected %d keys in new map, got %d", len(oldMap), len(newMap))
    }
    for k, v := range oldMap {
       if val, exists := newMap[k]; !exists || val != v {
          t.Errorf("Value for key %s in new map does not match original map", k)
       }
    }
}

// 測(cè)試 SyncMapToMap 函數(shù)
func TestSyncMapToMap(t *testing.T) {
    var syncMap sync.Map
    syncMap.Store("apple", 1)
    syncMap.Store("banana", 2)
    syncMap.Store("cherry", 3)
    m := SyncMapToMap[string, int](syncMap)
    syncMap.Range(func(key, value any) bool {
       k := key.(string)
       v := value.(int)
       if val, exists := m[k]; !exists || val != v {
          t.Errorf("Value for key %s in map does not match sync.Map", k)
       }
       return true
    })
}

// 測(cè)試 MapToSyncMap 函數(shù)
func TestMapToSyncMap(t *testing.T) {
    m := map[string]int{
       "apple":  1,
       "banana": 2,
       "cherry": 3,
    }
    syncMap := MapToSyncMap(m)
    for k, v := range m {
       value, exists := syncMap.Load(k)
       if !exists || value.(int) != v {
          t.Errorf("Value for key %s in sync.Map does not match original map", k)
       }
    }
}

總結(jié)

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

以上就是Go語(yǔ)言利用泛型封裝常見(jiàn)的Map操作的詳細(xì)內(nèi)容,更多關(guān)于Go泛型封裝Map操作的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Golang實(shí)現(xiàn)請(qǐng)求限流的幾種辦法(小結(jié))

    Golang實(shí)現(xiàn)請(qǐng)求限流的幾種辦法(小結(jié))

    這篇文章主要介紹了Golang實(shí)現(xiàn)請(qǐng)求限流的幾種辦法(小結(jié)),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • Golang解析JSON遇到的坑及解決方法

    Golang解析JSON遇到的坑及解決方法

    這篇文章主要為大家介紹了Golang解析JSON時(shí)會(huì)遇到的一些坑及解決方法,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Go語(yǔ)言有一點(diǎn)的幫助,需要的可以參考一下
    2023-02-02
  • Go語(yǔ)言的隊(duì)列和堆棧實(shí)現(xiàn)方法

    Go語(yǔ)言的隊(duì)列和堆棧實(shí)現(xiàn)方法

    這篇文章主要介紹了Go語(yǔ)言的隊(duì)列和堆棧實(shí)現(xiàn)方法,涉及container/list包的使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-02-02
  • Go使用XORM操作MySQL的陷阱盤點(diǎn)分析

    Go使用XORM操作MySQL的陷阱盤點(diǎn)分析

    在?Go?語(yǔ)言開(kāi)發(fā)中,大家為了方便,通常會(huì)選擇使用?ORM?操作數(shù)據(jù)庫(kù),比如使用?XORM?或?GORM?操作?MySQL,本文我們來(lái)介紹一下使用?XORM[3]?操作?MySQL?可能會(huì)遇到的陷阱
    2023-11-11
  • Go語(yǔ)言實(shí)現(xiàn)百萬(wàn)級(jí)WebSocket連接架構(gòu)設(shè)計(jì)及服務(wù)優(yōu)化

    Go語(yǔ)言實(shí)現(xiàn)百萬(wàn)級(jí)WebSocket連接架構(gòu)設(shè)計(jì)及服務(wù)優(yōu)化

    本文將詳細(xì)介紹如何在Go中構(gòu)建一個(gè)能夠支持百萬(wàn)級(jí)WebSocket連接的服務(wù),包括系統(tǒng)架構(gòu)設(shè)計(jì)、性能優(yōu)化策略以及具體的實(shí)現(xiàn)步驟和代碼示例
    2024-01-01
  • Golang的select多路復(fù)用及channel使用操作

    Golang的select多路復(fù)用及channel使用操作

    這篇文章主要介紹了Golang的select多路復(fù)用及channel使用操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-12-12
  • RabbitMQ延時(shí)消息隊(duì)列在golang中的使用詳解

    RabbitMQ延時(shí)消息隊(duì)列在golang中的使用詳解

    延時(shí)隊(duì)列常使用在某些業(yè)務(wù)場(chǎng)景,使用延時(shí)隊(duì)列可以簡(jiǎn)化系統(tǒng)的設(shè)計(jì)和開(kāi)發(fā)、提高系統(tǒng)的可靠性和可用性、提高系統(tǒng)的性能,下面我們就來(lái)看看如何在golang中使用RabbitMQ的延時(shí)消息隊(duì)列吧
    2023-11-11
  • 深度解析Go語(yǔ)言defer機(jī)制

    深度解析Go語(yǔ)言defer機(jī)制

    文章詳細(xì)介紹了Go語(yǔ)言中defer關(guān)鍵字的使用及其特性,涵蓋defer的基本用法、執(zhí)行時(shí)機(jī)、LIFO機(jī)制、與返回值的關(guān)系、在panic中的行為、參數(shù)求值時(shí)機(jī)、典型應(yīng)用場(chǎng)景及性能考量等,并通過(guò)示例代碼幫助理解,感興趣的朋友跟隨小編一起看看吧
    2026-04-04
  • Golang實(shí)現(xiàn)自己的Redis(有序集合跳表)實(shí)例探究

    Golang實(shí)現(xiàn)自己的Redis(有序集合跳表)實(shí)例探究

    這篇文章主要為大家介紹了Golang實(shí)現(xiàn)自己的Redis(有序集合跳表)實(shí)例探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-01-01
  • Go中的Context實(shí)現(xiàn)原理以及正確使用方式

    Go中的Context實(shí)現(xiàn)原理以及正確使用方式

    在 Go 語(yǔ)言中,Context 包是一種非常常用的工具,它被用來(lái)管理 goroutine 之間的通信和取消,本文將深入探討Context 包的基本原理,包括使用場(chǎng)景、原理和一些最佳實(shí)踐,感興趣的小伙伴跟著小編一起來(lái)看看吧
    2024-11-11

最新評(píng)論

武穴市| 德清县| 都江堰市| 梁平县| 伊通| 抚松县| 梁山县| 习水县| 武定县| 封丘县| 新津县| 宁海县| 布尔津县| 沛县| 临洮县| 涪陵区| 勃利县| 乌兰县| 通海县| 武城县| 沂水县| 搜索| 湘潭县| 启东市| 汶上县| 镇安县| 新民市| 孝感市| 定边县| 扎赉特旗| 靖安县| 志丹县| 宁化县| 西华县| 永顺县| 屯昌县| 安康市| 洪洞县| 芦溪县| 湖北省| 天水市|