GoLang 应用引擎结构名称

huangapple go评论98阅读模式
英文:

GoLang App Engine Struct Name

问题

最近我在使用AppEngine时遇到了一个问题,发现只有Date字段的值被写入了数据存储。我花了一些时间来解决这个问题,最后发现只需将结构体中的成员名称首字母大写即可解决!

我想知道是否还有其他人遇到过这个问题,并且知道为什么我不能在Golang结构体中使用小写的成员名称来操作数据存储?我认为这可能是Google AppEngine处理结构体写入时的一个bug。

以下是有问题的代码:

package main

import (
    "fmt"
    "net/http"
    "time"

    "appengine"
    "appengine/datastore"
)

/* 这是有问题的结构体 */
type storeVal struct {
    firstName    string  //FirstName可以工作
    lastName     string  //LastName可以工作
    email        string  //Email可以工作
    password     string  //Password可以工作
    Date         time.Time
}

func init() {
    http.HandleFunc("/", handle)
    http.ListenAndServe(":8080", nil)
}

func handle(w http.ResponseWriter, r *http.Request) {
    c := appengine.NewContext(r)

    /* 将值写入数据存储 */
    e1 := storeVal{
        firstName:      "Bob",                 //FirstName可以工作
        lastName:       "Smith",               //LastName可以工作
        email:          "bob.smith@test.com",  //Email可以工作
        password:       "password!",           //Password可以工作
        Date:           time.Now(),
    }

    key := datastore.NewIncompleteKey(c, "storeVal", nil)
    _, err := datastore.Put(c, key, &e1)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    fmt.Fprintf(w, "成功添加 {firstName: '%s', lastName: '%s', email: '%s', password: '%s'}", e1.firstName, e1.lastName, e1.email, e1.password)

    /* 读取值 */
    q := datastore.NewQuery("storeVal").
        Filter("firstName =", "Bob").
        Filter("lastName =", "Smith").
        Order("-Date")
    var storeVals []storeVal
    _, err2 := q.GetAll(c, &storeVals)
    if err2 != nil {
        http.Error(w, err2.Error(), http.StatusInternalServerError)
        return
    }
    if len(storeVals) == 0 {
        fmt.Printf("没有结果。")
        return
    }
    e2 := storeVals[0]
    fmt.Fprintf(w, "成功获取 {firstName: '%s', lastName: '%s', email: '%s', password: '%s', uaprem: '%s'}", e2.firstName, e2.lastName, e2.email, e2.password)
}
英文:

I was playing around with the AppEngine recently and came across an issue with the following code, where the only value that seemed to be written to the datastore was the Date. I spent a while banging my head on this to find that by simply capitalizing the first characters in the structs fixed it!

I was wondering if anyone else came across this and knows why I would be unable to use lowercase member names in the Golang struct for the datastore? I think that this may be a bug with the way the Google AppEngine handles struct writes.

Here's the problem code:

package main
import (
"fmt"
"net/http"
"time"
"appengine"
"appengine/datastore"
)
/* This is the problem struct */
type storeVal struct {
firstName    string  //FirstName works
lastName     string  //LastName works
email        string  //Email works
password     string  //Password works
Date         time.Time
}
func init() {
http.HandleFunc("/", handle)
http.ListenAndServe(":8080", nil)
}
func handle(w http.ResponseWriter, r *http.Request) {
c := appengine.NewContext(r)
/* Write values to DataStore */
e1 := storeVal{
firstName:     	"Bob",                 //FirstName works
lastName:     	"Smith",               //lastName works
email: 		    "bob.smith@test.com",  //Email works
password:  	    "password!",           //Password works
Date:  		    time.Now(),
}
key := datastore.NewIncompleteKey(c, "storeVal", nil)
_, err := datastore.Put(c, key, &e1)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
fmt.Fprintf(w, "successfully added {firstName: '%s', lastName: '%s', email: '%s', password: '%s'}", e1.firstName, e1.lastName, e1.email, e1.password)
/* Read values back in. */
q := datastore.NewQuery("storeVal").
Filter("firstName =", "Bob").
Filter("lastName =", "Smith").
Order("-Date")
var storeVals []storeVal
_, err2 := q.GetAll(c, &storeVals)
if err2 != nil {
http.Error(w, err2.Error(), http.StatusInternalServerError)
return
}
if (len(storeVals) == 0) {
fmt.Printf("No results.");
return
}
e2 := storeVals[0]
fmt.Fprintf(w, "successfully grabbed {firstName: '%s', lastName: '%s', email: '%s', password: '%s', uaprem: '%s'}", e2.firstName, e2.lastName, e2.email, e2.password)
}

答案1

得分: 5

这与Go语言处理“公共”和“私有”概念有关。

要导出字段,需要将字段名大写。这篇文章可以帮助解释这一点...它与JSON有关,但在这两种情况下都需要从结构体中导出数据。

这是我在Eager关于Go和JSON的博文中找到的有用信息:

字段名

正如你可能知道的,Go要求所有导出的字段以大写字母开头。
但在JSON中,这种风格并不常见。
我们使用标签来告诉解析器实际上在哪里查找值。

你可以在上面的示例中看到这个例子,但作为复习,它看起来像这样:

type MyStruct struct {
SomeField string `json:"some_field"`
}
英文:

It's related to how Go handles the "public" and "private" concept.

To export you do need the field names in caps. This can help explain that... it is related to JSON but it applies here as both cases require exporting the data from a struct.

This is from the Eager blog post on Go and JSON, which I found helpful:

> The Field Name
>
> As you might know, Go requires all exported fields to start with a
> capitalized letter.
> It’s not common to use that style in JSON however.
> We use the tag to let the parser know where to actually look for the
> value.
>
>
>
> You can see an example of that in the example above, but as a
> refresher this is what it looks like:
>
> type MyStruct struct {
> SomeField string json:"some_field"
> }

huangapple
  • 本文由 发表于 2015年8月9日 00:46:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/31896278.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定