为了账号安全,请及时绑定邮箱和手机立即绑定

如何在编译时使用四个ASCII代码创建常量uint32标签?

如何在编译时使用四个ASCII代码创建常量uint32标签?

Go
阿波罗的战车 2022-08-30 15:20:12
我需要创建许多uint32标签,这些标签是ASCII字母的映射。例如,标签“abcd”被编码为0x61626364其中每个字节对应于字母的ASCII代码。一个简单的解决方案是像这样定义标签值type Tag uint32const Tag_abcd = Tag(0x61626364)但这很容易出错。一个不太容易出错的解决方案是使用接收字母作为参数的函数来定义标记值。const Tag_abcd = foo("abcd")或者像这样,因为可以用C中的宏轻松完成const Tag_abcd = bar('a','b','c','d')但这需要支持在编译时评估的函数。据我所知,Go是不可能的。我说的对吗?能有别的办法吗?
查看完整描述

3 回答

?
白衣染霜花

TA贡献1796条经验 获得超10个赞

您可以使用符文文字和位移位来组装常量。它不会太紧凑,但它将是“安全的”(这意味着您可以在常量表达式中看到字符):


const TagABCD Tag = 'a'<<24 + 'b'<<16 + 'c'<<8 + 'd'

或者,您可以将其写在多行中,以便字母在列中对齐:


const TagABCD2 Tag = 0 +

    'a'<<24 +

    'b'<<16 +

    'c'<<8 +

    'd'


查看完整回答
反对 回复 2022-08-30
?
慕盖茨4494581

TA贡献1850条经验 获得超11个赞

要扩展 icza 的答案,并提高标签声明的可读性,您可以:

  • 以 的形式声明帮助器常量,其中 是相关的 ASCII 字符,并且是该字符在 4 个字符标记中的位置。<letter><number><letter><number>

  • 位移符文* 8

  • 通过 OR 'ing 帮助器常量来组合标记常量|

import "fmt"


const (

    a1 uint32 = 'a'<<(iota*8)

    a2

    a3

    a4

)


// other similar const declarations for b1,b2,b3,b4 and so on

// must repeat the keyword const to reset iota


const Tag_abcd = a4 | b3 | c2 | d1


const Tag_ddba = d4 | d3 | b2 | a1


func main() {

    fmt.Printf("%x\n", Tag_abcd) // 61626364

    fmt.Printf("%x\n", Tag_ddba) // 64646261

}

优点是:

  • 对于人类维护者来说,标签声明可能更容易阅读和直接

  • 借助 IDE 支持,可以轻松重构帮助程序标识符

缺点是:

  • 源可能会变得更加冗长,但您可以通过将帮助程序 const 隔离到单独的文件中来缓解这种情况

  • 对于大写的 ASCII,帮助程序将变为导出,因此您可能必须在标识符前面加上或类似的技巧A1_

断续器


查看完整回答
反对 回复 2022-08-30
?
开心每一天1111

TA贡献1836条经验 获得超13个赞

您可以使用 go generate 将复合常量值解析为不同的内存分配。

维护这个实现是相当复杂的,但是如果你有一个团队需要立即知道这有什么作用以及何时可以安全地重构它。


查看完整回答
反对 回复 2022-08-30
  • 3 回答
  • 0 关注
  • 87 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信