将JSON反序列化为UUID类型

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

Unmarshaling JSON into a UUID type

问题

我正在尝试使用json.Unmarshaler接口将UUID解组到结构体上的uuid.UUID字段。我创建了一个名为myUUID的自定义类型,一切都正常,直到我尝试访问通常在uuid.UUID上的方法时出现问题。我该如何处理这个问题?我对Go相对较新,所以也许我还不完全理解自定义类型。

package main

import (
    "encoding/json"
    "errors"
    "fmt"

    "code.google.com/p/go-uuid/uuid"
)

var jsonstring = `
{
    "uuid": "273b62ad-a99d-48be-8d80-ccc55ef688b4"
}

type myUUID uuid.UUID

type Data struct {
    uuid myUUID
}

func (u *myUUID) UnmarshalJson(b []byte) error {
    id := uuid.Parse(string(b[:]))
    if id == nil {
        return errors.New("Could not parse UUID")
    }
    *u = myUUID(id)
    return nil
}

func main() {
    d := new(Data)
    err := json.Unmarshal([]byte(jsonstring), &d)
    if err != nil {
        fmt.Printf("%s", err)
    }
    fmt.Println(d.uuid.String())
}

以下是翻译好的代码部分:

package main

import (
    "encoding/json"
    "errors"
    "fmt"

    "code.google.com/p/go-uuid/uuid"
)

var jsonstring = `
{
    "uuid": "273b62ad-a99d-48be-8d80-ccc55ef688b4"
}

type myUUID uuid.UUID

type Data struct {
    uuid myUUID
}

func (u *myUUID) UnmarshalJson(b []byte) error {
    id := uuid.Parse(string(b[:]))
    if id == nil {
        return errors.New("无法解析UUID")
    }
    *u = myUUID(id)
    return nil
}

func main() {
    d := new(Data)
    err := json.Unmarshal([]byte(jsonstring), &d)
    if err != nil {
        fmt.Printf("%s", err)
    }
    fmt.Println(d.uuid.String())
}

希望对你有帮助!如果还有其他问题,请随时提问。

英文:

I'm trying to use the json.Unmarshaler interface to unmarshal a UUID into a uuid.UUID field on a struct. I created a custom type called myUUID and everything works until I try to access methods that are normally on uuid.UUID. How can I handle this? I'm relatively new to Go, so maybe I just don't fully understand custom types just yet.

package main

import (
    "encoding/json"
    "errors"
    "fmt"

    "code.google.com/p/go-uuid/uuid"
)

var jsonstring = `
{
    "uuid": "273b62ad-a99d-48be-8d80-ccc55ef688b4"
}
`

type myUUID uuid.UUID

type Data struct {
    uuid myUUID
}

func (u *myUUID) UnmarshalJson(b []byte) error {
    id := uuid.Parse(string(b[:]))
    if id == nil {
            return errors.New("Could not parse UUID")
    }
    *u = myUUID(id)
    return nil
}

func main() {
    d := new(Data)
    err := json.Unmarshal([]byte(jsonstring), &d)
    if err != nil {
            fmt.Printf("%s", err)
    }
    fmt.Println(d.uuid.String())
}

答案1

得分: 8

你可能需要确保Data结构体中的myuuid变量是可见/导出的,即为"public"。对于类型别名MyUUID,也是同样的情况(而不是myUUID)。

type MyUUID uuid.UUID

type Data struct {
    Uuid MyUUID
}

根据JSON和Go

json包只访问结构体类型的导出字段(以大写字母开头的字段)。


正如Ainar G评论中所指出的,样式指南也建议:

名称中的首字母缩略词或首字母缩写词(例如"URL"或"NATO")应保持一致的大小写。例如,"URL"应该出现为"URL"或"url"(如"urlPony"或"URLPony"),而不是"Url"。这是一个例子:ServeHTTP而不是ServeHttp

当"ID"缩写为"identifier"时,也适用这个规则,所以应该写成"appID"而不是"appId"。

在你的情况下,这意味着:

type Data struct {
    UUID MyUUID
}
英文:

You might want to make sure your myuuid variable is visible/exported in the Data struct: as in "public".
Same for the type alias MyUUID (instead of myUUID)

type MyUUID uuid.UUID

type Data struct {
    Uuid MyUUID
}

From JSON and Go:

> The json package only accesses the exported fields of struct types (those that begin with an uppercase letter).


As commented by Ainar G, the style guide also recommends:

> Words in names that are initialisms or acronyms (e.g. "URL" or "NATO") have a consistent case.
For example, "URL" should appear as "URL" or "url" (as in "urlPony", or "URLPony"), never as "Url". Here's an example: ServeHTTP not ServeHttp.

> This rule also applies to "ID" when it is short for "identifier," so write "appID" instead of "appId".

In your case, that would mean:

type Data struct {
    UUID MyUUID
}

答案2

得分: 6

Go的自定义类型不继承方法。我使用自定义结构并附加了一个UnmarshalJSON来重构代码。

import (
        "errors"
        "strings"

        "github.com/pborman/uuid"
)


type ServiceID struct {
    UUID uuid.UUID
}

type Meta struct {
    Name    string `json:"name"`
    Version string `json:"version"`
    SID     *ServiceID `json:"UUID"`
}

func (self *ServiceID) UnmarshalJSON(b []byte) error {
    s := strings.Trim(string(b), "\"")
    self.UUID = uuid.Parse(s)
    if self.UUID == nil {
            return errors.New("Could not parse UUID")
    }
    return nil
}
英文:

Go's custom types don't inherit methods. I refactored the code using a custom struct and attaching an UnmarshalJSON.

import (
        "errors"
        "strings"

        "github.com/pborman/uuid"
)


type ServiceID struct {
    UUID uuid.UUID
}

type Meta struct {
    Name    string `json:"name"`
    Version string `json:"version"`
    SID     *ServiceID `json:"UUID"`
}

func (self *ServiceID) UnmarshalJSON(b []byte) error {
    s := strings.Trim(string(b), "\"")
    self.UUID = uuid.Parse(s)
    if self.UUID == nil {
            return errors.New("Could not parse UUID")
    }
    return nil
}

huangapple
  • 本文由 发表于 2014年8月12日 15:23:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/25258439.html
匿名

发表评论

匿名网友

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

确定