Почему я получаю сообщение об ошибке «Composite Literal Uses Unkeyed»?

Я относительно новичок в Go и работаю над созданием декодера запросов. Запрос приходит в формате JSON, и мы декодируем его в интерфейс map[string]{}. Затем мы передаем эти данные объекта для декодирования в нашу собственную структуру ProcessRequest. Как я уже сказал, я новичок, поэтому повторно использую некоторую логику в аналогичных частях кода, написанных предыдущими разработчиками. По сути, мы проверяем карту на наличие необходимых фрагментов, а затем устанавливаем и возвращаем их. Может ли кто-нибудь объяснить мне, почему я получаю заголовочную ошибку? Должен ли я устанавливать элементы вплоть до базовых структур, которые больше не имеют вложенности? Есть ли лучший способ выполнить то, что я хочу? Вот код и связанные структуры. Он выделяет ошибку при возврате model.ProcessRequest. ТИА

type ProcessRequest struct {
    RequestID string
    Message   *message.Message
    Rule      *Rule
    Options   *ProcessOptions
    //TODO: Context EvaluatorContext
    //TODO: Links
}

type Message struct {
    ID         int
    Key        string
    Source     string
    Headers    *HeaderSet
    Categories *CategorySet
    Properties *PropertySet
    Streams    *StreamSet
}

type RuleAction struct {
    Name       string
    Expression map[string]interface{}
}

type RuleLink struct {
    LinkID       int
    Condition    map[string]interface{}
    TargetRuleID int
}

type Rule struct {
    Name    string
    Code    string
    Actions []RuleAction
    Links   []RuleLink
}
type object = map[string]interface{}

func DecodeProcessRequest(dataObject map[string]interface{}) (*model.ProcessRequest, error) {
    var (
        requestID string
        message   *message.Message
        rule      *model.Rule
        options   *model.ProcessOptions
        err       error
    )

    if reqIDSrc, ok := dataObject["requestId"]; ok {
        if requestID, err = converter.ToString(reqIDSrc); err != nil {
            return nil, errors.Wrapf(err, "Error reading property 'requestID'")
        }
        if requestID == "" {
            return nil, errors.Errorf("Property 'requestID' is an empty string")
        }
    } else {
        return nil, errors.Errorf("Missing required property 'requestID'")
    }

    if messageSrc, ok := dataObject["message"]; ok {
        messageData, ok := messageSrc.(object)
        if !ok {
            return nil, errors.Errorf("Error reading property 'message': Value is not an object")
        }
        if message, err = DecodeMessage(messageData); err != nil {
            return nil, errors.Wrapf(err, "Error reading property 'message'")
        }
    } else {
        return nil, errors.Errorf("Missing required property 'message'")
    }

    if ruleSrc, ok := dataObject["rule"]; ok {
        ruleObj, ok := ruleSrc.(object)
        if !ok {
            return nil, errors.Errorf("Error reading property 'rule': Value is not an object")
        }
        if rule, err = DecodeRule(ruleObj); err != nil {
            return nil, errors.Wrapf(err, "Error reading 'rule' during decoding")
        }
    } else {
        return nil, errors.Errorf("Missing required property 'requestID'")
    }
    // Parse plain object to a Message struct
    return &model.ProcessRequest{
        requestID,
        message,
        rule,
        options,
    }, nil

}

Пожалуйста, включите сообщение об ошибке в вопрос и покажите, какая часть кода вызывает ошибку. Также всегда полезно удалить как можно больше кода. Сохраняйте ровно столько кода, сколько необходимо для воспроизведения ошибки. Посмотрите, как сделать минимальный воспроизводимый пример.

super 16.03.2022 15:10

В общем, в предупреждении говорится, что лучше использовать синтаксис ProcessRequest{ RequestID: requestID, ... }. Именование ключей вместо неключевых значений.

super 16.03.2022 15:13

Некоторые из значений structs, которые вы пытаетесь построить с помощью составной литерал, содержат поле с именем _ (единственное подчеркивание). Это заставляет компилятор отклонить определение, если только вы не используете нотацию FieldName: fieldValue для установки значений полей. Это своего рода хак, предназначенный для того, чтобы сделать такие литералы устойчивыми к изменениям порядка полей в определении таких struct типов.

kostix 16.03.2022 15:14

Спасибо, что добавили в RequestID: requestID устранил ошибку. Я не могу пометить это как ответ по какой-то причине?

CoderSchmoder 16.03.2022 15:17

В основном идея состоит в том, что если вы используете «неключевой» способ определения литералов структуры, значение ваших определений зависит от того, как расположены поля базового типа. Теперь учтите, что ваш тип имеет три поля типа string в определенном порядке. Теперь через пару итераций какой-нибудь программист переместит второе поле на 1-ю позицию — ваш литерал все еще будет компилироваться, но в конечном итоге во время выполнения будет определено совершенно другое значение.

kostix 16.03.2022 15:18
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
API ввода вопросов - это полезный инструмент для интеграции моделей машинного обучения, таких как ChatGPT, в приложения, требующие обработки...
1
5
49
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

супер сказал в этот комментарий:

In general, the warning says that you should prefer to use the syntax ProcessRequest{ RequestID: requestID, ... }. Naming the keys instead of unkeyed values.

Это сработало для меня. Также очень помогло объяснение костикс в этот комментарий.

Basically the idea is that if you use "unkeyed" way of defining struct literals, the meaning of your definitions depends on the way the fields of the underlying type are layed out. Now consider that your type has three fields of type string in a certain order. Now a couple of iterations down the road some programmer moves the second field to the 1st position—your literal will still compile but will end up defining a completely different value at runtime.

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