CGO项目中stringer无法处理取值来自C枚举的Go常量如何解决?
问题解决方法
错误根因
stringer工具默认采用语法解析模式直接读取Go源码,不会执行CGO预处理逻辑,因此无法识别C.GIT_DELTA_*这类C侧枚举常量对应的实际整数值,才会抛出constant is not an integer的错误。
解决方案
方案一:使用stringer的packages模式(推荐,无侵入兼容CGO)
- 先升级stringer到最新版本,确保支持packages模式和标签传递:
go install golang.org/x/tools/cmd/stringer@latest
- 两种执行方式二选一即可:
- 方式1:修改diff.go中的generate注解,替换原有注解为:
//go:generate stringer -type Delta -trimprefix Delta -tags "static,system_libgit2" -mode packages
修改完成后执行命令:
go generate -tags static,system_libgit2 ./diff.go
- 方式2:直接手动执行stringer命令,无需修改源码:
stringer -type Delta -trimprefix Delta -tags "static,system_libgit2" -mode packages ./diff.go
执行完成后会在当前目录生成delta_string.go文件,即为所需的字符串映射文件。
方案二:硬编码常量值(仅应急使用)
如果不想更新stringer或者临时需要生成文件,可以将C枚举值直接硬编码到Go常量定义中,和你本地安装的libgit2版本的枚举值对应即可:
const ( DeltaUnmodified Delta = 0 DeltaAdded Delta = 1 DeltaDeleted Delta = 2 DeltaModified Delta = 3 DeltaRenamed Delta = 4 DeltaCopied Delta = 5 DeltaIgnored Delta = 6 DeltaUntracked Delta = 7 DeltaTypeChange Delta = 8 DeltaUnreadable Delta = 9 DeltaConflicted Delta = 10 )
修改完成后直接执行原有generate命令即可正常生成文件,缺点是libgit2版本更新后枚举值可能变动,需要手动同步。
内容的提问来源于stack exchange,提问作者Kirill
相关产品推荐
相关产品推荐

