英文:
Can't store byte array in google's datastore
问题
我正在使用Google的Datastore在我的Go应用程序中。我有一个Song
结构体,其中有一个uuid.UUID
字段。
type Song struct {
ID: uuid.UUID
Title: string
...
}
这个UUID
是从github.com/satori/go.uuid获取的,并且被定义为
type UUID [16]byte
看起来Datastore无法处理字节数组,但在这种情况下只能处理字节切片或字符串。在json
包中,我可以使用标签将其解释为字符串
type Song struct {
ID: uuid.UUID `json:"id,string"`
....
}
有没有办法告诉Datastore将UUID
解释为切片/字符串,或者我必须放弃"类型"安全性,只存储一个字符串或使用自定义的PropertyLoadSaver
?
英文:
I'm using Google's datastore in my Go app. I have a Song
struct, which has a uuid.UUID
field.
type Song struct {
ID: uuid.UUID
Title: string
...
}
This UUID
is taken from github.com/satori/go.uuid and is defined as
type UUID [16]byte
It seems that datastore can't handle byte arrays but in this use case only byte slices or strings. In the json
package I can use a tag to interpret it as a string
type Song struct {
ID: uuid.UUID `json:"id,string"`
....
}
Is there a way of telling datastore to interpret the UUID
as a slice/string or do I either have to give up "type"-safety and just store a string or use a custom PropertyLoadSaver
?
答案1
得分: 3
根据Google的文档:
有效的值类型包括:
- 有符号整数(int、int8、int16、int32和int64)
- 布尔值(bool)
- 字符串(string)
- 浮点数(float32和float64)
- 字节切片([]byte,长度最多为1兆字节)
- 任何底层类型为上述预声明类型之一的类型
- ByteString
- *Key
- time.Time(以微秒精度存储)
- appengine.BlobKey
- appengine.GeoPoint
- 所有字段都是有效值类型的结构体
- 上述任何类型的切片
因此,你需要使用字节切片或字符串。当需要进行设置或获取时,你可以进行一些后台操作,例如(Playground示例):
type uuid [16]byte
type song struct {
u []byte
}
func main() {
var b [16]byte
copy(b[:], "0123456789012345")
var u uuid = uuid(b) // 表示获取到的uuid
s := song{u: []byte(u[:])}
copy(b[:], s.u)
u = uuid(b)
fmt.Println(u)
}
也可以通过方法来实现(Playground示例)。
另外,你还可以创建一个特定于数据存储的实体,其中包含字节切片,并且用于转换的转换器知道如何进行转换。
英文:
> Valid value types are:
>
- signed integers (int, int8, int16, int32 and int64),
- bool,
- string,
- float32 and float64,
- []byte (up to 1 megabyte in length),
- any type whose underlying type is one of the above predeclared types,
- ByteString,
- *Key,
- time.Time (stored with microsecond precision),
- appengine.BlobKey,
- appengine.GeoPoint,
- structs whose fields are all valid value types,
- slices of any of the above.
So, you will have to use a byte slice or string. You could do some behind the scenes manipulation when you need to do your setting or getting like (Playground Example):
type uuid [16]byte
type song struct {
u []byte
}
func main() {
var b [16]byte
copy(b[:], "0123456789012345")
var u uuid = uuid(b) //this would represent when you get the uuid
s := song{u: []byte(u[:])}
copy(b[:], s.u)
u = uuid(b)
fmt.Println(u)
}
This could also be done through methods. (Playground example)
Alternatively, you could have an entity specific to the datastore that carries the byte slice, and the transformers that go to and from that entity know how to do the conversion.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论