[英]How to implement BitSet with Go?
我没有在Go中找到BitSet包,所以我尝试实现它。 我想使用uint64数组来存储这些位。
我需要分配uint64数组的位数。 使用Java,我可以定义一个带整数的构造函数。 虽然Go不提供构造函数,但是当用户调用new()时如何正确初始化BitSet'对象'?
如果使用[] uint64切片来存储数据,则零切片可以用作空BitSet。 事实上,附加到nil切片会为您分配一个新数组,尽管语言规范似乎并不能保证这一点。 通过这种设置,新的(BitSet)可以立即使用。 例:
bitset.go:
package bitset
const size = 64
type bits uint64
// BitSet is a set of bits that can be set, cleared and queried.
type BitSet []bits
// Set ensures that the given bit is set in the BitSet.
func (s *BitSet) Set(i uint) {
if len(*s) < int(i/size+1) {
r := make([]bits, i/size+1)
copy(r, *s)
*s = r
}
(*s)[i/size] |= 1 << (i % size)
}
// Clear ensures that the given bit is cleared (not set) in the BitSet.
func (s *BitSet) Clear(i uint) {
if len(*s) >= int(i/size+1) {
(*s)[i/size] &^= 1 << (i % size)
}
}
// IsSet returns true if the given bit is set, false if it is cleared.
func (s *BitSet) IsSet(i uint) bool {
return (*s)[i/size]&(1<<(i%size)) != 0
}
bitset_test.go:
package bitset
import "fmt"
func ExampleBitSet() {
s := new(BitSet)
s.Set(13)
s.Set(45)
s.Clear(13)
fmt.Printf("s.IsSet(13) = %t; s.IsSet(45) = %t; s.IsSet(30) = %t\n",
s.IsSet(13), s.IsSet(45), s.IsSet(30))
// Output: s.IsSet(13) = false; s.IsSet(45) = true; s.IsSet(30) = false
}
将bitSet声明为私有结构:
type bitSet struct {
len int
array []uint64
}
公开接口BitSet:
type BitSet interface {
Has(pos int) bool
Add(pos int) bool
Len() int
}
还公开一个函数NewBitSet:
func NewBitSet(len int) BitSet {
return &bitSet{len, make(uint64, (len+7) / 8) }
}
这是封装的Go方式:共享接口,而不是实现。
简短的回答是,当客户端调用new
()时,无法正确初始化BitSet
对象。
你可以做的最好的事情是使你的BitSet
的零值有效。 这就是list.List
, sync.Mutex
和big.Int
这样的类型。 这样您就知道客户端无法获得无效值。
您可以做的下一件事是创建类似于NewBitSet
函数(在本例中名为NewBitSet
)并期望客户端调用它。
Go的标准big.Int
可以用作位集:
package main
import (
"fmt"
"math/big"
)
func main() {
var bits big.Int
for i := 1000; i < 2000; i++ {
bits.SetBit(&bits, i, 1)
}
for i := 0; i < 10000; i++ {
if bits.Bit(i) != 0 {
fmt.Println(i)
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.