如何在golang结构中使用bit而不是bool?

type EventPrefs struct {
    Call          bool
    Presence      bool 
    Endpoint      bool
    VoiceMail     bool
    CallRecording bool
}

目前,该结构类型的大小为 5 个字节,但我想使用位。有没有办法做到这一点?

回答

Go中没有“位”类型,所以如果你想把多个bool 信息打包成位,你必须自己实现。声明一个类型uint8(或uint16任何其他整数类型)的字段,并提供获取/设置字段特定位的方法。

一般位设置/清除就像这样简单:

var masks = []uint8{0x01, 0x02, 0x04, 0x08, 0x10}

func set(field, data uint8, b bool) uint8 {
    if b {
        return data | masks[field] // Set bit
    }
    return data ^ masks[field] // Clear bit
}

func get(field, data uint8) bool {
    return data&masks[field] != 0
}

将 5 个布尔字段打包成一个uint8值:

type EventPrefs struct {
    data uint8
}

func (e *EventPrefs) SetCall(b bool) { e.data = set(0, e.data, b) }
func (e *EventPrefs) Call() bool     { return get(0, e.data) }

func (e *EventPrefs) SetPresence(b bool) { e.data = set(1, e.data, b) }
func (e *EventPrefs) Presence() bool     { return get(1, e.data) }

func (e *EventPrefs) SetEndpoint(b bool) { e.data = set(2, e.data, b) }
func (e *EventPrefs) Endpoint() bool     { return get(2, e.data) }

func (e *EventPrefs) SetVoiceMail(b bool) { e.data = set(3, e.data, b) }
func (e *EventPrefs) VoiceMail() bool     { return get(3, e.data) }

func (e *EventPrefs) SetCallRecording(b bool) { e.data = set(4, e.data, b) }
func (e *EventPrefs) CallRecording() bool     { return get(4, e.data) }

测试它:

ep := &EventPrefs{}

fmt.Println("Calls:", ep.Call(), ep.data)
ep.SetCall(true)
fmt.Println("Calls:", ep.Call(), ep.data)

fmt.Println("Presence:", ep.Presence(), ep.data)
ep.SetPresence(true)
fmt.Println("Presence:", ep.Presence(), ep.data)
ep.SetPresence(false)
fmt.Println("Presence:", ep.Presence(), ep.data)

哪些输出(在Go Playground上试试):

Calls: false 0
Calls: true 1
Presence: false 1
Presence: true 3
Presence: false 1

节省 4 个字节值得吗?很少。

注意:上述解决方案可以有很多变化。例如,掩码可以使用位移“计算”,set()get()函数可以是EventPrefsand 的方法,因此data不需要参数(并且set()可以直接设置EventPrefs.data字段,因此也不需要返回值)。如果set()仍然是一个函数,则dataparam 可能是一个指针,因此set()可以在不返回新的情况下更改指向的值data等。该data字段可能有自己的声明类型,例如bitpackwithget()set()方法附加到它。

请参阅相关:某些运算符“|”、“^”、“&”、“&^”之间的区别。高朗


以上是如何在golang结构中使用bit而不是bool?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>