【问题标题】:Spread operator analogue扩展运算符模拟
【发布时间】:2019-02-25 16:31:49
【问题描述】:

我有一个结构和该结构的实例:

type Obj struct {
  ssid string
  code string
  mit string
  // and other props (23)
}

var ValidObject = Obj {
  ssid: "AK93-KADJ9-92J76",
  code: "SKO-120O"
  mit: "MSLA-923-OKSW"
}

我想创建一个结构切片(Obj),其中包含ValidObject,只更改了一些字段。我认为最好的解释方法是使用伪代码,所以这里是(使用来自 JS 的扩展运算符 :)):

var slc = []Obj{
  {
    ...ValidObject,
    code: "Other value",
  },
  {
    ...ValidObject,
    mit: "Other value"
  }
}

【问题讨论】:

  • go 确实有扩展运算符,但不幸的是它不适用于 js 中的扩展运算符之类的对象,您必须创建辅助函数

标签: go struct slice


【解决方案1】:

创建一个辅助函数,接受 Object,更改其 code 并返回新的 Object

func withCode(obj Obj, code string) Obj {
    obj.code = code
    return obj
}

注意withCode取的是非指针值,所以你传递的Object不会被修改,只会修改本地副本。

使用这个你的任务是:

var slc = []Obj{
    withCode(ValidObject, "Other value"),
    withCode(ValidObject, "Yet another value"),
}
fmt.Println(slc)

输出(在Go Playground 上试试):

[{AK93-KADJ9-92J76 Other value MSLA-923-OKSW}
    {AK93-KADJ9-92J76 Yet another value MSLA-923-OKSW}]

这个助手withCode 甚至可以是一个方法(而不是一个函数)。

请注意,如果您需要多个字段的变体,最好将它们添加为方法,这样您就可以链接调用。

例如:

func (o Obj) withCode(code string) Obj {
    o.code = code
    return o
}

func (o Obj) withSsid(ssid string) Obj {
    o.ssid = ssid
    return o
}

func (o Obj) withMit(mit string) Obj {
    o.mit = mit
    return o
}

然后使用它:

var slc = []Obj{
    ValidObject.withCode("code2").withSsid("ssid2"),
    ValidObject.withMit("mit2").withSsid("ssid3"),
}
fmt.Println(slc)

输出(在Go Playground上试试):

[{ssid2 code2 MSLA-923-OKSW} {ssid3 SKO-120O mit2}]

【讨论】:

  • 所以这意味着我需要为我想要更改的每个字段创建一个辅助函数?
  • @Src 您可以向withCode() 添加更多参数以更改多个字段(但您可能会将其命名为其他名称)。
  • 问题是我一次只需要更改一个字段..对于切片中的每个项目
  • @Src 您可以创建类似:withCode(obj, paramName, paramValue) 的函数,但在这种情况下您必须使用反射,而且速度很慢(
  • @Src 查看已编辑的答案,添加多种方法,使用任何你想使用的方法,甚至可以将它们链接起来。
【解决方案2】:

全局创建一个结构体切片var objCollector = []obj{},并将数据读入定义的结构体,并将append对象读入我们创建的结构体切片。

type Obj struct {
    ssid string
    code string
    mit  string
}

var objCollector = []obj{}

func main() {
    var ValidObject = Obj{
        ssid: "AK93-KADJ9-92J76",
        code: "SKO-120O",
        mit:  "MSLA-923-OKSW",
    }
    append(objectCollector, ValidObject)
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-20
    • 2016-09-20
    • 2020-04-13
    • 2018-07-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多