go - 类型没有字段或方法读取(但它有)

标签 go thrift

我被这个难住了。在我正在从事的项目中,我们从 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/

相关文章:

elasticsearch - 在 google go 中使用 olivere/elastic 通过 ElasticSearch 中的查询更新记录

caching - Go 是否缓存 DNS 查找?

ssl - 在 Go 中使用 SSL 终止和 HTTP/2 的 HAProxy

java - 关于如何在 Thrift(客户端/服务器)中使用 TFileTransport 的示例

java - 在 Python 中使用 HTTPS 的示例 Apache Thrift 服务

python - 当我使用Thrift将C++中的映射序列化到磁盘,然后使用Python反序列化时,我没有得到相同的对象

linux - 调试器在带有 "Go"插件的 IntelliJ IDEA 中不起作用

macos - 链接器 stub 文件警告

c++ - thrift 中的 Union 显示 c++ 中设置的所有值

hadoop - hive - 工作跟踪?