「GoCN酷Go推薦」go語言位操作庫 — bitset
bitset庫實現(xiàn)了bitsets數(shù)據(jù)結(jié)構(gòu),這是一種正整數(shù)和布爾值映射關(guān)系的結(jié)構(gòu),它比map[uint]bool更高效
什么是bitsets?
bitsets基本思想是用一個bit位來標記某個元素對應(yīng)的Value,每一位表示一個數(shù),1表示存在,0表示不存在 比如我要表示1, 3, 7這3個數(shù)
構(gòu)造一個空白bitsets:00000000 每位代表的值如下:76543210 想要表示的值標記1:10001010
有什么好處??
最大的好處是節(jié)省存儲空間,假設(shè)有20億個正整數(shù)中找出m是否在其中 如果每個數(shù)字用int存儲,占8byte,2000000000 * 8 = 14G 如果用bit存儲每個數(shù)字,占1bit,2000000000 / 8 = 0.233G 由此可見bitsets節(jié)省了極大的存儲空間
Usage?
安裝
go?get?github.com/bits-and-blooms/bitset
基本操作
//?構(gòu)造一個64bit長度的bitset
b?:=?bitset.New(64)
//?放入一個數(shù)
b.Set(10)
fmt.Println(b.DumpAsBits())?//?000000000000000000000000000000000000000000000000010000000000
//?刪除一個值
b.Clear(10)
fmt.Println(b.DumpAsBits())?//?000000000000000000000000000000000000000000000000000000000000
//?長度
b.Set(1).Set(3)
fmt.Println(b.Len())?//?64
//?測試
fmt.Println(b.Test(3))?//?true
fmt.Println(b.Test(4))?//?false
指定位置操作
b?:=?&bitset.BitSet{}
b.Set(3)
//?在指定位置插入0
b.InsertAt(3)
fmt.Println(b.DumpAsBits())?//?000000000000000000000000000000000000000000000000000000010000
//?在指定位置修改
b.SetTo(4,?false)
fmt.Println(b.DumpAsBits())?//?000000000000000000000000000000000000000000000000000000000000
//?指定位置刪除
b.Set(3).DeleteAt(3)?//?000000000000000000000000000000000000000000000000000000000000
兩個bitsets交互
a?:=?&bitset.BitSet{}
a.Set(1).Set(3).Set(5)
b?:=?&bitset.BitSet{}
b.Set(3).Set(5).Set(7)
//?交集
fmt.Println(a.Intersection(b))?//?{3,5}
//?并集
fmt.Println(a.Union(b))?//?{1,3,5,7}
//?差集
fmt.Println(a.Difference(b))?//?{1}
//?全等
fmt.Println(a.Equal(b))?//?false
遍歷
b?:=?bitset.New(64)
b.Set(1).Set(3).Set(5).Set(7)
for?i,?e?:=?b.NextSet(0);?e;?i,?e?=?b.NextSet(i?+?1)?{
????fmt.Println("The?following?bit?is?set:",?i)
}
//?The?following?bit?is?set:?1
//?The?following?bit?is?set:?3
//?The?following?bit?is?set:?5
//?The?following?bit?is?set:?7
實例?
假設(shè)現(xiàn)在數(shù)據(jù)庫里有一個字段存儲用戶狀態(tài),設(shè)計是這樣的:0 00 00 第1、2位表示會員等級 00表示普通會員,01表示vip1,10表示vip2,11表示svip 第3、4位表示頭像狀態(tài) 00表示未上傳,01表示01審核中,10審核失敗,11審核通過 第5位表示賬號狀狀態(tài) 0表示正常,1表示封禁
b?:=?bitset.New(5)
//?設(shè)置vip1,第1位0,第2位1
b.SetTo(1,?false).SetTo(2,?true)
//?設(shè)置頭像審核失敗,第3位1,第4位0
b.SetTo(3,?true).SetTo(4,?false)
//?狀態(tài)初始化
b.ClearAll()
//?查看賬號狀態(tài),第5位,true代表1?false代表0
b.Test(5)?
//?是不是svip,第1、2位是11
b.Test(1)?&&?b.Test(2)
總結(jié)?
bitset/bitmap在日常開發(fā)中會經(jīng)常用到,在特定場景下有很好的效果。這個庫可以簡化操作bitset/bitmap的難度,而且這個庫的源碼也很好的演示了go的位操作
官方文檔:https://github.com/bits-and-blooms/bitset
《酷Go推薦》招募:
各位Gopher同學(xué),最近我們社區(qū)打算推出一個類似GoCN每日新聞的新欄目《酷Go推薦》,主要是每周推薦一個庫或者好的項目,然后寫一點這個庫使用方法或者優(yōu)點之類的,這樣可以真正的幫助到大家能夠?qū)W習(xí)到
新的庫,并且知道怎么用。
大概規(guī)則和每日新聞類似,如果報名人多的話每個人一個月輪到一次,歡迎大家報名!戳「閱讀原文」,即可報名
掃碼也可以加入 GoCN 的大家族喲~
