惯用golang:访问和更新结构中的项目

时间:2014-11-13 12:57:32

标签: arrays pointers go

所以我试着编写一些代码,允许我在结构中编辑数组中的值。此示例使用"状态"作为一个可能的改变价值,但这只是一个简化,试图让我的意图。

package main

import(
  "fmt"
)

type Parent struct {
  Children []Child
}

type Child struct {
  Status string
}

func (p *Parent) Add() *Child {
  var child Child
  child.Status = "1"
  p.Children = append(p.Children, child)
  return &p.Children[len(p.Children)-1]
}

func main() {
  var p Parent
  child := p.Add()
  child.Status = "2"
  fmt.Println(p)
  fmt.Println(child)
}

这并不适合"正确"。我怎么能在golang中这样做?当然我可以将值作为参数传递,但在我的特定情况下,我想在添加子项后编辑Child结构内部的函数指针(不在此代码中以保持简短)。感觉更好,但也许我只需要将它们作为参数传递给Add方法?

例如

func (p *Parent) Add(fn1 func(), fn2 func()) *Child {

无论如何只是想知道是否有人对这种情况有任何想法。

3 个答案:

答案 0 :(得分:2)

我认为您应该在Add方法之外创建Child并将其传入。如果您想操纵Child,请在传入之前执行此操作。您可以使用{{1}上的方法} struct来做到这一点:

Child

答案 1 :(得分:1)

我建议以最简单的方式做到这一点。记住KISS原则。 系统的一部分只做一件事。

遵循此逻辑,您的Add(c *Child)方法应该只添加一个孩子。创建Child应该单独完成,同样为Child提供一些独特的属性。

对于您的OpenGL菜单系统,这种方法也非常适合:

m := NewMenu()
t := NewText(text)
t.OnClick = someCallback
// Some other t initialisation.
m.Add(t)
// Some time later you can still change t if it's a pointer and m.Add
// doesn't copy.
t.OnHover = someOtherCallback

是否保留您的标签导出或隐藏它们并提供getter / setter的决定取决于您,并且完全取决于您的系统的设计和一致性要求。

答案 2 :(得分:1)

好的,以下适用于我。代码再次更改,以便更清楚地关注我遇到的特定问题。这一切都归结为正确使用指针。感谢您的建议。

package main

import (
    "fmt"
)

type HairColor func() string
type Parent struct {
    Children []*Child
}

type Child struct {
    Age           int
    ShowHairColor HairColor
}

func (p *Parent) Add(c *Child) {
    p.Children = append(p.Children, c)
}

func main() {
    var parent Parent
    var child Child

    child.Age = 10
    parent.Add(&child)

    child.ShowHairColor = func() string {
        return "red"
    }
    fmt.Printf("%v\n", parent.Children[0])
    fmt.Printf("%v\n", child)

    fmt.Println(parent.Children[0].ShowHairColor())
}