为什么会出现 "Composite Literal Uses Unkeyed" 错误?

Why do I get "Composite Literal Uses Unkeyed" error?

我是 Go 的新手,正在构建一个请求解码器。请求采用 JSON 格式,我们将其解码为 map[string]interface{}。然后我们将要解码的 object 数据传递给我们自己的 ProcessRequest 结构。正如我所说,我是新手,所以我在以前开发人员编写的代码的类似部分中重复使用了一些逻辑。本质上,我们正在检查地图中是否有必要的部分,然后设置并 returning 这些。有人可以向我解释为什么我会收到标题错误吗?我是否必须将项目一直设置为不再有任何嵌套的基本结构?有没有更好的方法来完成我想要的?这是代码和相关结构。它突出显示 model.ProcessRequest 的 return 上的错误。蒂亚

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 said in :

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

这对我有用。 kostix in 的解释也很有帮助。

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.