我被这个难住了。在我正在从事的项目中,我们从 Thrift 生成 go 代码。代码是在包 A/B/thriftapi 中创建的(它曾经是 A/B/thrift,这导致了问题,因为所有生成的代码都导入了 git.apache.org/thrift.git/lib/go/thrift
并导致名称冲突)。
我生成了代码并将代码移动到 $GOPATH/src/A/B/D
然后我尝试构建我的项目并且遇到了大量错误的形式:
p.X.Read undefined (type Foo has no field or method Read)
我查看了其中一条违规行:
import (
"A/B/D"
"git.apache.org/thrift.git/lib/go/thrift"
)
func(p *Bar) readField1(iprot thrift.TProtocol) error {
p.X = D.NewFoo()
if err := p.X.Read(iprot); err != nil {
...
}
因为我使用的是 IntelliJ,所以我按住 CTRL 并单击了 Read()
方法,果然它跳转到了 $GOPATH/A/B/D/ttypes.go
方法
func (p *Foo) Read(iprot thrift.TProtocol) error {
...
}
这正是我希望方法所在的文件,它是指向 Foo
的指针上的方法,所以没有问题。一切似乎都应该是正确的,但在 IntelliJ 和命令行中我都遇到了这些问题。
任何想法可能出了什么问题?当它告诉我该方法不存在时令人沮丧,但如果我单击它(并且还会在智能感知中弹出),我会直接使用它
编辑 - 根据评论
type Bar struct {
X Foo `thrift:"x,1,required"`
}
最佳答案
这是您所看到内容的最小复制。
package main
type A struct{}
type B *A
func (a *A) Read() {}
func main() {
var b B
b.Read()
}
编译产生这个错误信息:
prog.go:11: b.Read undefined (type B has no field or method Read)
问题在于 thrift 正在定义它自己的 Foo
,即 *D.Foo
,这就是 b.X
的类型。 D.Foo
类型在我的代码中用A
表示,thrift引入的Foo
类型用B表示
。虽然 *D.Foo
有一个 Read()
方法,但是 Foo
别名没有。这就是您看到错误消息的原因。在您的情况下,错误消息令人困惑,因为 Foo
模棱两可地引用 D.Foo
或错误文本中的 thrift 别名 - 编译器意味着其中之一,并且您正在将其解释为另一个意思。
您可以通过编写 (*D.Foo)(b.X).Read()
或在复制情况下将值转换为正确的类型来解决别名问题:
package main
type A struct{}
type B *A
func (a *A) Read() {}
func main() {
var b B
(*A)(b).Read()
}
关于go - 类型没有字段或方法读取(但它有),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28907976/