英文:
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"
> }
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论