<p>View boolslice on <a href="https://github.com/mkideal/pkg/blob/master/container/boolslice/boolslice.go" rel="nofollow">github</a></p>
<pre><code>package boolslice
type BoolSlice struct {
data []byte
length int
}
func New() *BoolSlice {
return &BoolSlice{data: []byte{}}
}
func NewWithSize(size, cap int) *BoolSlice {
return &BoolSlice{data: make([]byte, (size+7)>>3, (cap+7)>>3), length: size}
}
func NewWithSlice(slice []bool) *BoolSlice {
size := len(slice)
s := NewWithSize(size, size)
for i := 0; i < size; i++ {
s.Set(i, slice[i])
}
return s
}
func (s *BoolSlice) ij(index int) (i int, j byte) { return index >> 3, byte(index & 0x7) }
func (s *BoolSlice) Get(index int) bool {
i, j := s.ij(index)
return s.data[i]&(1<<j) != 0
}
func (s *BoolSlice) Set(index int, value bool) {
i, j := s.ij(index)
if value {
s.data[i] |= 1 << j
} else {
s.data[i] &= ^(1 << j)
}
}
func (s *BoolSlice) Push(value bool) {
i, j := s.ij(s.length)
if i >= len(s.data) {
s.data = append(s.data, 0)
}
if value {
s.data[i] |= 1 << j
} else {
s.data[i] &= ^(1 << j)
}
s.length++
}
func (s *BoolSlice) Pop() (value bool) {
if s.length == 0 {
panic("length == 0")
}
s.length--
value = s.Get(s.length)
if n := (s.length >> 3) + 1; n < len(s.data) {
s.data = s.data[:n]
}
return
}
func (s *BoolSlice) Insert(index int, value bool) {
s.Push(value)
for i := s.length - 1; i > index; i-- {
s.Set(i, s.Get(i-1))
}
s.Set(index, value)
}
func (s *BoolSlice) Truncate(from, to int) {
if to < s.length {
s.length = to
if n := (s.length >> 3) + 1; n < len(s.data) {
s.data = s.data[:n]
}
}
if from > 0 {
l := to - from
for i := 0; i < l; i++ {
s.Set(i, s.Get(i+from))
}
s.length = l
if n := (s.length >> 3) + 1; n < len(s.data) {
s.data = s.data[:n]
}
}
}
func (s *BoolSlice) Clone() *BoolSlice {
s2 := &BoolSlice{data: make([]byte, s.length), length: s.length}
copy(s2.data, s.data)
return s2
}
func (s *BoolSlice) Equal(s2 *BoolSlice) bool {
if s.length != s2.length {
return false
}
for i, n := 0, len(s.data); i < n; i++ {
if s.data[i] != s2.data[i] {
return false
}
}
return true
}
func (s *BoolSlice) EqualToSlice(s2 []bool) bool {
if s.Len() != len(s2) {
return false
}
for i, n := 0, s.Len(); i < n; i++ {
if s.Get(i) != s2[i] {
return false
}
}
return true
}
</code></pre>
<hr/>**评论:**<br/><br/>allhatenocattle: <pre><p>could you make this without the length field and just use length(data) when you need it? </p>
<p>For Pop() I wouldn't panic, but might return 2 values like a get from a map, where first field is the value, 2nd is if there was an entry found.</p></pre>tucnak: <pre><p>So you made a bitset?</p></pre>tadvi: <pre><p>It seems that only 4 bools per one byte? Why not make it 8 bools per byte?</p></pre>ChristophBerger: <pre><p>It's difficult to see but the code does store 8 bools per byte.</p>
<p><code>func ij()</code> returns two values:</p>
<pre><code>i := index >> 3
</code></pre>
<p>This is the same as index/8, to turn bit index into byte index.</p>
<pre><code>j := byte(index & 0x7)
</code></pre>
<p>This masks all but the lowest three bits (0x7 is 0b111). These are the bits that were lost in the <code>index >> 3</code>operation. They repesent a value between 0 and 7, which is the index of the bit within the i-th byte.</p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传