Перейти к сборке с ошибкой буфера протокола: слишком мало значений в struct initializer

У меня есть файл прото:

syntax = "proto3";

package main;

message Client {
    int32 Id = 1;
    string Name = 2;
    string Email = 3;
}

Скомпилированный Client структура, как показано ниже:

type Client struct {
    Id                   int32    `protobuf:"varint,1,opt,name=Id,proto3" json:"Id,omitempty"`
    Name                 string   `protobuf:"bytes,2,opt,name=Name,proto3" json:"Name,omitempty"`
    Email                string   `protobuf:"bytes,3,opt,name=Email,proto3" json:"Email,omitempty"`
    XXX_NoUnkeyedLiteral struct{} `json:"-"`
    XXX_unrecognized     []byte   `json:"-"`
    XXX_sizecache        int32    `json:"-"`
}

Когда я пытаюсь начать это Client структура, как показано ниже:

client := &Client{123, "John", "john@aol.com"}

Я получаю ошибку здания: too few values in struct initializer, Я нашел способ исправить это, добавив XXX_NoUnkeyedLiteral, XXX_unrecognized, XXX_sizecache, Я не знаю, что это такое, и задаюсь вопросом, является ли это правильным способом сделать это:

client := &Client{123, "John", "john@aol.com", struct{}{}, []byte{}, int32(0)}

2 ответа

Решение

В составных литералах структуры вы можете опускать имена полей, для которых вы перечисляете значения (это называется литералом без ключа), но затем вы должны перечислить начальные значения для всех полей и в порядке их объявления. Или вы можете использовать ключевой литерал, в котором вы явно указываете, для каких полей вы указываете начальные значения. В последнем случае вам разрешено пропускать любое из полей, вы можете просто перечислить те, которые вы хотите дать начальному значению, отличному от нулевого значения поля).

Вы использовали составной литерал без ключа, и в этом случае вы должны перечислить значения для всех полей, чего вы не сделали. Вот что говорит вам сообщение об ошибке: "слишком мало значений в struct initializer".

Имя поля (генерируется protobuf) само по себе должно дать вам подсказку: XXX_NoUnkeyedLiteral, Он предлагает вам не использовать составной литерал без ключей.

Поэтому используйте составной литерал с ключами, например так:

client := &Client{
    Id:    123,
    Name:  "John",
    Email: "john@aol.com",
}

Эта форма более читабельна и не подвержена изменениям структуры. Например, если Client struct получит новые поля, или поля будут переупорядочены, этот код все равно будет действительным и компилируемым.

Добавьте имя поля до того, как значение сможет устранить ошибку здания, так как

client := &Client{Id: 123, Name: "John", Email: "john@aol.com"}

Я узнаю об этом, проверив пример grpc golang, но, может быть, кто-нибудь может объяснить, почему?;)

Другие вопросы по тегам