Golang實(shí)現(xiàn)支持多種類(lèi)型的set
寫(xiě)在前面
今天項(xiàng)目中需要用到string類(lèi)型的set,想起來(lái)項(xiàng)目中不少地方都需要,而且都是用map[string]bool實(shí)現(xiàn)的,既然這么多地方用到set去重,為什么不寫(xiě)一個(gè)set呢?而且go現(xiàn)在支持了泛型,為啥不寫(xiě)一個(gè)支持多種類(lèi)型的set呢?說(shuō)干就干
代碼
package set
var (
ElemValue = struct{}{}
)
type SetType interface {
int | int32 | int64 | string | float32 | float64
}
// Set[T SetType]. 集合,線程不安全
type Set[T SetType] interface {
Add(T)
Remove(T)
Contains(T) bool
Empty() bool
Values() []T
}
type set[T SetType] struct {
m map[T]struct{}
}
func NewSet[T SetType](ss ...T) Set[T] {
newSet := set[T]{
m: make(map[T]struct{}, len(ss)),
}
for _, s := range ss {
newSet.Add(s)
}
return &newSet
}
func (s *set[T]) Add(elem T) {
s.m[elem] = ElemValue
}
func (s *set[T]) Remove(elem T) {
delete(s.m, elem)
}
func (s *set[T]) Contains(elem T) bool {
_, ok := s.m[elem]
return ok
}
func (s *set[T]) Empty() bool {
empty := true
for _, _ = range s.m {
empty = false
break
}
return empty
}
func (s *set[T]) Values() []T {
ss := make([]T, 0)
for k, _ := range s.m {
ss = append(ss, k)
}
return ss
}寫(xiě)完之后發(fā)現(xiàn)才60多行代碼,非常簡(jiǎn)單,而且value使用的是struct{}{},不占用任何內(nèi)存
單測(cè)
package set_test
import (
"set"
"testing"
"github.com/stretchr/testify/assert"
)
func TestStringSet(t *testing.T) {
newSet := set.NewSet[string]("a", "b")
assert.False(t, newSet.Empty())
newSet.Add("c")
newSet.Remove("a")
assert.False(t, newSet.Contains("a"))
assert.True(t, newSet.Contains("c"))
newSet.Remove("c")
result := newSet.Values()
assert.Equal(t, "b", result[0])
}
func TestInt64Set(t *testing.T) {
newSet := set.NewSet[int64](1, 2)
assert.False(t, newSet.Empty())
newSet.Add(3)
newSet.Remove(1)
assert.False(t, newSet.Contains(1))
assert.True(t, newSet.Contains(3))
newSet.Remove(3)
result := newSet.Values()
assert.Equal(t, int64(2), result[0])
}造輪子感想
之前沒(méi)有用過(guò)go 泛型,今天寫(xiě)這個(gè)set體驗(yàn)了一下泛型,確實(shí)挺好用的。本人喜歡造輪子、支持造輪子。只有這樣才能提升自己,一起學(xué)習(xí)吧
到此這篇關(guān)于Golang實(shí)現(xiàn)支持多種類(lèi)型的set的文章就介紹到這了,更多相關(guān)Golang實(shí)現(xiàn)set內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Go微服務(wù)網(wǎng)關(guān)的實(shí)現(xiàn)
本文主要介紹了Go微服務(wù)網(wǎng)關(guān)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07
Go語(yǔ)言學(xué)習(xí)之函數(shù)的定義與使用詳解
這篇文章主要為大家詳細(xì)介紹Go語(yǔ)言中函數(shù)的定義與使用,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Go語(yǔ)言有一定幫助,需要的可以參考一下2022-04-04
Go基礎(chǔ)教程系列之WaitGroup用法實(shí)例詳解
這篇文章主要介紹了Go基礎(chǔ)教程系列之WaitGroup用法實(shí)例詳解,需要的朋友可以參考下2022-04-04
Golang設(shè)計(jì)模式之單例模式詳細(xì)講解
單例模式很容易記住。就像名稱(chēng)一樣,它只能提供對(duì)象的單一實(shí)例,保證一個(gè)類(lèi)只有一個(gè)實(shí)例,并提供一個(gè)全局訪問(wèn)該實(shí)例的方法。本文就來(lái)聊聊Go語(yǔ)言中的單例模式,感興趣的小伙伴可以了解一下2023-01-01
Golang使用channel實(shí)現(xiàn)數(shù)據(jù)匯總的方法詳解
這篇文章主要為大家詳細(xì)介紹了在并發(fā)編程中數(shù)據(jù)匯總的問(wèn)題,并探討了在并發(fā)環(huán)境下使用互斥鎖和通道兩種方式來(lái)保證數(shù)據(jù)安全性的方法,需要的可以參考一下2023-05-05
golang程序進(jìn)度條實(shí)現(xiàn)示例詳解
這篇文章主要為大家介紹了golang程序?qū)崿F(xiàn)進(jìn)度條示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08
Go語(yǔ)言使用漏桶算法和令牌桶算法來(lái)實(shí)現(xiàn)API限流
為防止服務(wù)器被過(guò)多的請(qǐng)求壓垮,限流是一個(gè)至關(guān)重要的技術(shù)手段,下面我們就來(lái)看看如何使用漏桶算法和令牌桶算法來(lái)實(shí)現(xiàn) API 的限流吧2024-11-11

