首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Go: Bitfield和bit打包

Go: Bitfield和bit打包
EN

Stack Overflow用户
提问于 2011-04-27 00:05:11
回答 2查看 8.7K关注 0票数 11

C语言的位域提供了一种在结构中定义任意宽度字段的相当方便的方法(暂时不考虑可移植性的问题)。例如,下面是一个简单的结构,包含几个字段和一个“flag”:

代码语言:javascript
复制
#pragma pack(push,1)
struct my_chunk{

    unsigned short fieldA: 16;
    unsigned short fieldB: 15;
    unsigned short fieldC:  1;
};
#pragma pop()

添加#杂注语句可将此结构打包为32位字(例如,确保my_chunk指针的指针操作与节省的空间一致)。

访问每个字段在语法上是非常好的:

代码语言:javascript
复制
struct my_chunk aChunk;
aChunk.fieldA = 3;
aChunk.fieldB = 2;
aChunk.fieldC = 1;

在没有语言帮助的情况下,另一种实现方式相当丑陋,而且很可能会被转移到汇编语言中。例如,一种解决方案是为您想要访问的每个字段设置位移宏:

代码语言:javascript
复制
#define FIELD_A  0xFF00
#define FIELD_B  0x00FE
#define FIELD_C  0x0001

#define get_field(p, f) ((*p)&f)
#define set_field(p, f, v) (*p) = (v<<f) + (*p)&(~f)

...
set_field(&my_chunk, FIELD_A, 12345);

。。或者类似的东西(有关更正式的信息,请查看this)

所以问题是,如果我想在go中“做”位域,那么最好的做法是什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-04-27 01:54:10

"There are no current plans for struct bitfields in Go."

你可以写一个Go包来做这件事;不需要汇编程序。

票数 13
EN

Stack Overflow用户

发布于 2011-05-03 12:52:21

如果目标仅仅是拥有一个非常小的结构,你可能会这样做:

代码语言:javascript
复制
package main

import "fmt"

type my_chunk uint32

func (c my_chunk) A() uint16 {
  return uint16((c & 0xffff0000) >> 16) 
}

func (c *my_chunk) SetA(a uint16) {
  v := uint32(*c)
  *c = my_chunk((v & 0xffff) | (uint32(a) << 16))
}

func main() {
  x := my_chunk(123)
  x.SetA(12)
  fmt.Println(x.A())
}

使用当前的6g/8g,您将看到一个带有大约6条getter指令的函数调用,随着时间的推移,这样的调用可能会被内联。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5793098

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档