dongtangu8615 2015-03-06 21:27
浏览 182
已采纳

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

I'm stumped on this one. In the project that I'm working on, we generate go code from Thrift. The code gets created in the package A/B/thriftapi (which used to be A/B/thrift which was causing problems because all of the generated code was importing git.apache.org/thrift.git/lib/go/thrift and causing name collisions).

I generated the code and moved the code into $GOPATH/src/A/B/D I then tried to build my project and was getting tons of errors of the form:

p.X.Read undefined (type Foo has no field or method Read)

I looked at one of the offending lines:

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 { 
    ...
 }

Since I am using IntelliJ, I CTRL+clicked on the Read() method and sure enough it jumps to $GOPATH/A/B/D/ttypes.go to the method

func (p *Foo) Read(iprot thrift.TProtocol) error {
    ...
}

That's exactly the file I'd expect the method to be in, and it's a method on a pointer to Foo so no problems there. Everything seems like it should be right, but both in IntelliJ and on the command line I get these problems.

Any ideas what might be going wrong? It's frustrating when it tells me the method doesn't exist, yet will take me right to it if I click on it (and also pops up in the intellisense)

EDIT - Per comment

type Bar struct {
   X Foo `thrift:"x,1,required"`    
}
  • 写回答

3条回答 默认 最新

  • doushan5245 2015-03-09 18:19
    关注

    As @Anyonymous points out, this is a problem with thrift aliasing and using the wrong one. I consider this a bug in the Thrift compiler (in 0.9.2 and current HEAD) in that it will generate code that will never work. We haven't run into this problem with other languages, just go. Here is a simplification to reproduce the problem:

    // Base.thrift
    namespace go a.X.c
    struct Foo {
        1: required string s
    }
    

    and the depenant file

    // Child.thrift
    namespace go a.Y.c
    include "Base.thrift"
    
    typedef Base.Foo Foo // <---- This is what causes the problem
    
    struct Bar {
        1:Foo f  // <-- Will error
        // 1:Base.Foo f   Need to comment out typedef and use this instead
    }
    

    Compiling the thrift as is will be fine, but when you go to install the a.Y.c package will produce:

    /scratch/go/src/a/Y/c/ttypes.go:78: cannot use c.Foo literal (type *c.Foo) as type *Foo in assignment
    /scratch/go/src/a/Y/c/ttypes.go:79: p.F.Read undefined (type *Foo has no field or method Read)
    /scratch/go/src/a/Y/c/ttypes.go:105: p.F.Write undefined (type *Foo has no field or method Write)
    

    If I comment out the typedef and swap the lines in Bar then everything works fine. This appears to only happen in Go.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 yolov7训练自己的数据集
  • ¥15 esp8266与51单片机连接问题(标签-单片机|关键词-串口)(相关搜索:51单片机|单片机|测试代码)
  • ¥15 电力市场出清matlab yalmip kkt 双层优化问题
  • ¥30 ros小车路径规划实现不了,如何解决?(操作系统-ubuntu)
  • ¥20 matlab yalmip kkt 双层优化问题
  • ¥15 如何在3D高斯飞溅的渲染的场景中获得一个可控的旋转物体
  • ¥88 实在没有想法,需要个思路
  • ¥15 MATLAB报错输入参数太多
  • ¥15 python中合并修改日期相同的CSV文件并按照修改日期的名字命名文件
  • ¥15 有赏,i卡绘世画不出