【问题标题】:Protobuf/Go cannot use literal * (type *) as type * in array or slice literal [closed]Protobuf/Go 不能在数组或切片文字中使用文字 *(类型 *)作为类型 * [关闭]
【发布时间】:2020-03-18 06:43:34
【问题描述】:

我在生成的 proto 文件中有一个结构,看起来像这样(简化):

type Record struct {
    Field1           int64  `protobuf:"varint,1,opt,name=field1,proto3" json:"field1,omitempty"`
    Field2           []byte `protobuf:"bytes,2,opt,name=field2,proto3" json:"field2,omitempty"`
}

我正在尝试在我的 Go 文件中调用它

func foo(c messagepb.MessageServiceClient){
    fmt.Println("Starting to send message...")

    msgs := []*messagepb.MessageRequest{
        recordpb.Record{ //error msg here
            Field1:             1,
            Field2:             []byte{byte('a')},
        }
    }

    ...
}

但我在 recordpb.Record 行收到此错误:

cannot use recordpb.Record literal (type recordpb.Record) as type *messagepb.MessageRequest in array or slice literal

如果有帮助,这是我的messagepb

message.proto

message MessageRequest { recordpb.Record records = 1; }

message.pb.go

type MessageRequest struct {
    Record               *recordpb.Record `protobuf:"bytes,1,opt,name=record,proto3" json:"record,omitempty"`
}

我找不到任何有用的信息来说明为什么会发生这种情况...有什么想法吗?

【问题讨论】:

  • 您可能还需要一组花括号。能否展示一下 MessageRequest 类型的 Go 定义?
  • 考虑到MessageRequest的附加定义,我“不认为”,我知道是缺少花括号。
  • 请注意,额外的花括号集用于初始化切片内的元素。例如,表达式[]T{} 称为composite literal,该表达式初始化一个长度和容量为零的Ts 切片。然而,可以编写一个复合文字,用您想要的尽可能多的元素初始化切片,例如表达式[]T{T{}, T{}}(一个包含其元素的两个复合文字的切片复合文字)产生一个长度和容量为 2 .
  • 现在在切片、数组和映射文字中,您可以在编写元素的复合文字时省略类型,因此 []T{T{}, T{}} 可以缩短为 []T{{}, {}},生成的切片将是一样。

标签: go proto


【解决方案1】:

看起来您正在创建[]*messagepb.MessageRequest 的切片,然后向其添加recordpb.Recordrecordpb.Record*messagepb.MessageRequest 的类型不同。

鉴于这种类型

type MessageRequest struct {
    Record *recordpb.Record `protobuf:"bytes,1,opt,name=record,proto3" json:"record,omitempty"`
}

看起来你的 msgs 变量应该是

msgs := []*messagepb.MessageRequest{
    {
        Record: &recordpb.Record{
            Field1: 1,
            Field2: []byte{byte('a')},
        },
    },
}

@mkopriva 的 cmets 对此添加了一些很好的解释。

【讨论】:

  • 谢谢!我被困在这个问题上很长时间了。在 {} 上的 @mkopriva 的 cmets 顶部,您的回答让我意识到我在 MessageRequest 中缺少 Record :)
  • @IceTea 请注意,在 struct literal 中,如果您提供给它的值的数量等于该 可访问 字段的数量结构,您可以省略字段。换句话说,在这种情况下,您可以从文字中省略 Record:,只要确保有花括号即可:只要 MessageRequest 只有一个字段,[]*messagepb.MessageRequest{{&recordpb.Record{}}} 就可以工作字段的类型是recordpb.Record
  • @IceTea 在here 中有一节介绍适用于结构文字的规则。与上述注释相关的是:“不包含任何键的元素列表必须按照声明字段的顺序为每个结构字段列出一个元素。”“如果任何元素有一个键,那么每个元素都必须有一个键。” play.golang.com/p/eHnPh_QhWPW
猜你喜欢
  • 2017-05-12
  • 2021-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-02
  • 1970-01-01
相关资源
最近更新 更多