go語言中數(shù)據(jù)接口set集合的實(shí)現(xiàn)
概述
set 是一種常用的數(shù)據(jù)結(jié)構(gòu),它表示一組唯一元素的集合。在不同的編程語言和庫中,set 可能有不同的實(shí)現(xiàn)方式和特性。
set 集合數(shù)據(jù)結(jié)構(gòu)具有以下特性:
- 唯一性:set 中的元素是唯一的,不允許重復(fù)。這意味著在 set 中添加重復(fù)的元素不會(huì)產(chǎn)生任何變化。
- 無序性:set 中的元素沒有順序。不能通過索引訪問 set 中的元素,也不能對 set 中的元素進(jìn)行排序。
- 可變性:set 通常是可變的,這意味著你可以添加或刪除元素。
- 集合運(yùn)算:set 支持多種集合運(yùn)算,如并集、交集和差集。
Go語言中最常用的兩種數(shù)據(jù)結(jié)構(gòu)分別是 slice 和 map。 除了 Go 內(nèi)置的數(shù)據(jù)結(jié)構(gòu),還有一些數(shù)據(jù)結(jié)構(gòu)是由 Go 的官方 container 包提供,如 heap 堆、list 雙向鏈表和ring 回環(huán)鏈表。但Go語言中并沒有內(nèi)置set這種數(shù)據(jù)結(jié)構(gòu)。本文聊聊go語言中set的實(shí)現(xiàn)方式。
我們知道 map 的鍵是具有唯一性,所以可以用 map 來實(shí)現(xiàn)數(shù)據(jù)結(jié)構(gòu) set。
set的實(shí)現(xiàn)
使用map使用一個(gè)set集合,意味著我們只關(guān)心 key 的存在,其 value 值并不重要,直接將vlaue設(shè)置為空接口。
package main import ( "errors" "fmt" "sync" ) /* 用map實(shí)現(xiàn)一個(gè)線程安全的set */ type void struct{} var member void type IData interface{} type Set struct { mapset map[IData]struct{} mutex sync.Mutex } func NewSet() *Set { return &Set{ mapset: make(map[IData]struct{}), mutex: sync.Mutex{}, } } func (s *Set) Add(data IData) bool { s.mutex.Lock() defer s.mutex.Unlock() s.mapset[data] = member return true } func (s *Set) Remove(data IData) error { s.mutex.Lock() defer s.mutex.Unlock() for k, _ := range s.mapset { if k == data { delete(s.mapset, k) return nil } } return errors.New("not found") } func (s *Set) Pop() IData { s.mutex.Lock() defer s.mutex.Unlock() if len(s.mapset) <= 0 { return nil } for k, _ := range s.mapset { return s.mapset[k] } return nil } func (s *Set) Size() int { s.mutex.Lock() defer s.mutex.Unlock() return len(s.mapset) } func (s *Set) All() []IData { s.mutex.Lock() defer s.mutex.Unlock() datas := make([]IData, 0) for k, _ := range s.mapset { datas = append(datas, k) } return datas } func main() { // test myset := NewSet() myset.Add(1) myset.Add(2) myset.Add(1) fmt.Println(myset.All()) // [1 2] myset.Add(3) fmt.Println(myset.Size()) //3 fmt.Println(myset.All()) // [1 2 3] myset.Remove(2) fmt.Println(myset.All()) // [1 2 3] }
set的三方庫
在kubernetes中也實(shí)現(xiàn)了stirng,int32,int43,byte等幾種基本類型為值的set集合。接下來我們分析下源碼實(shí)現(xiàn)。找到源碼為位置k8s.io/apimachinery/pkg/util/sets
// sets.String is a set of strings, implemented via map[string]struct{} for minimal memory consumption. // String類型定義,使用map來實(shí)現(xiàn)set集合,集合的元素是string type String map[string]Empty // NewString creates a String from a list of values. // 構(gòu)造一個(gè)set,set集合存放的值是string類型 func NewString(items ...string) String { ss := String{} ss.Insert(items...) return ss } // Insert adds items to the set. // 插入元素到集合 func (s String) Insert(items ...string) String { for _, item := range items { s[item] = Empty{} } return s } // Delete removes all items from the set. // 從set中刪除指定string func (s String) Delete(items ...string) String { for _, item := range items { delete(s, item) } return s } // Has returns true if and only if item is contained in the set. // 判斷set是否包含指定的string func (s String) Has(item string) bool { _, contained := s[item] return contained } // HasAll returns true if and only if all items are contained in the set. // 判斷set是否包括一組所有的字符串 func (s String) HasAll(items ...string) bool { for _, item := range items { if !s.Has(item) { return false } } return true } // HasAny returns true if any items are contained in the set. // 判斷一組字符串是否有包括在set中 func (s String) HasAny(items ...string) bool { for _, item := range items { if s.Has(item) { return true } } return false }
總結(jié)
本文介紹了set的特點(diǎn),并介紹go語言中如何用map實(shí)現(xiàn)一個(gè)set,最后我們分析了kubernete源碼中的set庫的源碼。由于源碼比較簡單,就沒有展開分析。
到此這篇關(guān)于go語言中數(shù)據(jù)接口set集合的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)go語言 set集合內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
go?doudou開發(fā)單體RESTful服務(wù)快速上手教程
這篇文章主要為大家介紹了go?doudou開發(fā)單體RESTful服務(wù)快速上手教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12深入分析Golang Server源碼實(shí)現(xiàn)過程
這篇文章深入介紹了Golang Server源碼實(shí)現(xiàn)過程,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2023-02-02GO?CountMinSketch計(jì)數(shù)器(布隆過濾器思想的近似計(jì)數(shù)器)
這篇文章主要介紹了GO?CountMinSketch計(jì)數(shù)器(布隆過濾器思想的近似計(jì)數(shù)器),文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的朋友可以參考一下2022-09-09從零封裝Gin框架實(shí)現(xiàn)日志初始化及切割歸檔功能
這篇文章主要為大家介紹了從零封裝Gin框架實(shí)現(xiàn)日志初始化及切割歸檔功能示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01淺談golang fasthttp踩坑經(jīng)驗(yàn)
本文主要介紹了golang fasthttp踩坑經(jīng)驗(yàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11