在 Go 中,由于类型不兼容,我遇到了编译错误,我无法解释。我正在使用该"C"模块。最小示例包含以下 2 个文件:
package module
import "C"
type T struct {
X C.int
}
Run Code Online (Sandbox Code Playgroud)
和一个主程序
package main
import (
"fmt"
"sandbox/module"
)
import "C"
func f() *module.T {
var x C.int = 42
return &module.T{X: x}
}
func main() {
fmt.Printf("value: %d", f().X)
}
Run Code Online (Sandbox Code Playgroud)
这无法编译并显示消息
./main.go:12: cannot use x (type C.int) as type module.C.int in field value。
由于某种原因,编译器认为C.int不等于module.C.int。
它一定与模块有关,C并且代码分布在两个模块中,因为如果我从C.intplain切换到它,它会突然起作用int。
为什么这段代码不能编译?使其编译而不将所有代码压缩在一个模块中的正确解决方案是什么?
我在 Ubuntu 16.04 上使用最新的 Go 编译器 1.9.2。
Cgo 将 C 类型转换为等效的未导出的 Go 类型。由于翻译未导出,因此 Go 包不应在其导出的 API 中公开 C 类型:一个 Go 包中使用的 C 类型与另一个 Go 包中使用的相同 C 类型不同。
你说,“出于某种原因,编译器认为 C.int 不等于 module.C.int。” 正如 cgo 命令文档所解释的,不同包中未导出的 Go 类型并不相同。
不要在导出的 API 中公开 C 类型。例如,
module.go:
package module
type T struct {
X int
}
Run Code Online (Sandbox Code Playgroud)
main.go:
package main
import (
"fmt"
"sandbox/module"
)
import "C"
func f() *module.T {
var x C.int = 42
return &module.T{X: int(x)}
}
func main() {
fmt.Printf("value: %d\n", f().X)
}
Run Code Online (Sandbox Code Playgroud)
输出:
value: 42
Run Code Online (Sandbox Code Playgroud)