简体   繁体   English

Golang常数结构键

[英]Golang constant struct key

In PHP we can do something like: 在PHP中,我们可以执行以下操作:

if ($env == "dev") 
  define("key", "key")
else
  define("key", "secret")

// json ouput
//{ key : "value" } or { secret : "value" }

How do I properly translate above PHP approach to GO? 如何正确地将上述PHP方法转换为GO?

I was thinking of something like: 我在想类似的东西:

if *env == "dev" {
  type response struct {
    key string
    ...50 more keys that should also be different depending on env
  }
} else {
    secret string
    ...50 more keys...
}

But I guess that is not only wrong but would also create a huge repeated code... 但是我想这不仅是错误的,而且还会创建大量重复的代码...

You may create a struct type holding the common part of your data structure, and you may create new types embedding this and only adding the deviating new field. 您可以创建一个包含数据结构公共部分的结构类型,也可以创建嵌入该结构的新类型,并仅添加偏离的新字段。 So there is no code repetition of the common part of the data structure: 因此,数据结构的公共部分没有代码重复:

type Response struct {
    F1 string
    F2 int
}

func main() {
    for _, env := range []string{"dev", "prod"} {
        if env == "dev" {
            type Resp struct {
                Response
                Key string
            }
            r := Resp{Response{"f1dev", 1}, "value"}
            json.NewEncoder(os.Stdout).Encode(r)
        } else {
            type Resp struct {
                Response
                Secret string
            }
            r := Resp{Response{"f1pro", 2}, "value"}
            json.NewEncoder(os.Stdout).Encode(r)
        }
    }
}

Output (try it on the Go Playground ): 输出(在Go Playground上尝试):

{"F1":"f1dev","F2":1,"Key":"value"}
{"F1":"f1pro","F2":2,"Secret":"value"}

Note that you may also use the same Response value if they are the same for the 2 use cases: 请注意,如果两个用例的Response值相同,则也可以使用相同的Response值:

comResp := Response{"f1value", 1}
if env == "dev" {
    type Resp struct {
        Response
        Key string
    }
    r := Resp{comResp, "value"}
    json.NewEncoder(os.Stdout).Encode(r)
} else {
    type Resp struct {
        Response
        Secret string
    }
    r := Resp{comResp, "value"}
    json.NewEncoder(os.Stdout).Encode(r)
}

You may shorten the code above by using anonymous struct and not creating a local variable (not necessarily more readable): 您可以使用匿名结构而不创建局部变量(不一定更具可读性)来缩短上述代码:

if env == "dev" {
    json.NewEncoder(os.Stdout).Encode(struct {
        Response
        Key string
    }{comResp, "value"})
} else {
    json.NewEncoder(os.Stdout).Encode(struct {
        Response
        Secret string
    }{comResp, "value"})
}

Use a variable: 使用变量:

var key = "secret"
if env == "dev" {
   key = "dev"
}

Use that variable when creating a map to serialize to JSON: 创建映射以序列化为JSON时,请使用该变量:

m := map[string]interface{}{key: "value"}
p, err := json.Marshal(m)
if err != nil {
   // handle error
}
// p contains the json value.

playground example 游乐场的例子

The answer to this question depends on your actual use case. 这个问题的答案取决于您的实际用例。 Here are 3 ways to achieve what you ask: 这里有3种方法来实现您的要求:

  1. Use map[string]interface{} instead of struct 使用map[string]interface{}代替struct
  2. Use different struct types (as in the example from the question) 使用不同的结构类型(如问题示例所示)
  3. Use a single struct type that contains fields for both "dev" and "prod" environments, use "json:,omitempty" and populate only necessary fields before marshalling to JSON. 使用包含“开发”和“生产”环境的字段的单一结构类型,使用“ json:,omitempty”,并在编组为JSON之前仅填充必要的字段。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM