我对Go很陌生,到目前为止,我一直很喜欢。但是,我无法终生解决。

我有一个简单的包装,发票。

type Invoice struct {
    key datastore.Key
    Name string
    Created time.Time
    Updated time.Time
    lineItems []LineItem
}

发票有多个LineItem。
type LineItem struct {
    key datastore.Key
    InvoiceKey *datastore.Key
    Name string
    Description string
}

我的包裹有几个功能。
func New(c appengine.Context) (i Invoice)
func (i *Invoice) Update()
func (i *Invoice) Save(c appengine.Context)
func (i *Invoice) AddLineItem(c appengine.Context, name string)

New()返回一个新的Invoice,并将datastore.NewIncompleteKey()生成的密钥保存为Invoice中的未导出变量,以便以后保存。

所有这些都运行良好,这是否是正确的方法是另一个问题。我也愿意对此发表评论。我似乎无法弄清楚的是最后一个功能。
func (i *Invoice) AddLineItem(c appengine.Context, name string) {
    key := datastore.NewIncompleteKey(c, "LineItem", &i.key)
    lineItem := LineItem{key: *key, InvoiceKey: &i.key, Name: name}
    i.lineItems = append(i.lineItems, lineItem)
}

然后在Save()中
for _, lineItem := range i.lineItems {
    _, err := datastore.Put(c, &lineItem.key, &lineItem)
    if err != nil {
        panic(err)
    }
}

我在这里一直收到无效的密钥错误。我基本上只是想使发票具有许多LineItems的功能。能够将它们全部保存到数据存储中,然后根据需要拉出带有所有LineItem的整个发票。

我在正确的轨道上吗?有一个更好的方法吗?

最佳答案

您的lineItems []LineItemkey datastore.Key未导出,它们需要以大写字母开头,否则GAE将无法使用它。
specs:

标识符可以被导出以允许从另一个包访问它。如果同时满足以下条件,则导出标识符:

  • 标识符名称的第一个字符是Unicode大写字母(Unicode类“Lu”);和
  • 标识符在包块中声明,或者它是字段名称或方法名称。

  • 所有其他标识符都不会导出。

    10-08 17:16