有什么方法可以处理Golang中带有空格的Google数据存储区实物名称?

I'm running in a nasty issue with Datastore that doesn't appear to have any workaround.

I'm using the Google Appengine Datastore package to pull back projection query results into Appengine memory for manipulation, and that is being accomplished with representing each entity as a Struct, with each Struct field corresponding to a Property name, like so:

type Row struct {
Prop1    string
Prop2    int
}

This works great, but I've extended my queries into reading other property names that have spaces. While the query runs fine, it can't pull the data back into structs as it's looking to place the given value into a struct of the same naming convention, and I'm getting this kind of error:

datastore: cannot load field "Viewed Registration Page" into a "main.Row": no such struct field

Obviously Golang cannot represent a struct field like this. There is a field of the relevant type but no obvious way to tell the query to place it there.

What would be the best solution here?

Cheers

Actually Go supports mapping entity property names to different struct field names using tags (see this answer for details: What are the use(s) for tags in Go?).

For example:

type Row struct {
    Prop1    string `datastore:"Prop1InDs"`
    Prop2    int    `datastore:"p2"`
}

But the Go implementation of the datastore package panics if you attempt to use a property name which contains a space.

To sum it up: you can't map property names having spaces to struct fields in Go (this is an implementation restriction which may change in the future).

But the good news is that you can still load these entities, just not into struct values.

You may load them into a variable of type datastore.PropertyList. datastore.PropertyList is basically a slice of datastore.Property, where Property is a struct which holds the name of the property, its value and other info.

This is how it can be done:

k := datastore.NewKey(ctx, "YourEntityName", "", 1, nil) // Create the key
e := datastore.PropertyList{}

if err := datastore.Get(ctx, k, &e); err != nil {
    panic(err) // Handle error
}

// Now e holds your entity, let's list all its properties.
// PropertyList is a slice, so we can simply "range" over it:
for _, p := range e {
    ctx.Infof("Property %q = %q", p.Name, p.Value)
}

If your entity has a property "Have space" with value "the_value", you will see for example:

2016-05-05 18:33:47,372 INFO: Property "Have space" = "the_value"

Note that you could implement the datastore.PropertyLoadSaver type on your struct and handle this under the hood, so basically you could still load such entities into struct values, but you have to implement this yourself.

But fight for entity names and property names to not have spaces. You will make your life harder and miserable if you allow these.

All programming languages that I know treat a space as the end of a variable/constant name. The obvious solution is to avoid using spaces in property names.

I would also note that a property name becomes a part of every entity and every index entry. I don't know if Google somehow compresses them, but I tend to use short property names in any case.

You can use annotations to rename properties.

From the docs:

// A and B are renamed to a and b.
// A, C and J are not indexed.
// D's tag is equivalent to having no tag at all (E).
// I is ignored entirely by the datastore.
// J has tag information for both the datastore and json packages.
type TaggedStruct struct {
    A int `datastore:"a,noindex"`
    B int `datastore:"b"`
    C int `datastore:",noindex"`
    D int `datastore:""`
    E int
    I int `datastore:"-"`
    J int `datastore:",noindex" json:"j"`
}