猿问

将 JSON 解码为接口值

由于 encoding/json 需要一个非 nil 接口来解组:我如何可靠地制作用户提供的指针类型的(完整)副本,将其存储在我的User接口中,然后 JSON 解码为该临时?


注意:这里的目标是实现“无人值守”——即从 Redis/BoltDB 中提取字节,解码为接口类型,然后检查GetID()接口定义的方法是否返回非空字符串,以及请求中间件。


游乐场:http : //play.golang.org/p/rYODiNrfWw


package main


import (

    "bytes"

    "encoding/json"

    "fmt"

    "log"

    "net/http"

    "os"


    "time"

)


type session struct {

    ID      string

    User    User

    Expires int64

}


type User interface {

    GetID() string

}


type LocalUser struct {

    ID      string

    Name    string

    Created time.Time

}


func (u *LocalUser) GetID() string {

    return u.ID

}


type Auth struct {

    key []byte

    // We store an instance of userType here so we can unmarshal into it when

    // deserializing from JSON (or other non-gob decoders) into *session.User.

    // Attempting to unmarshal into a nil session.User would otherwise fail.

    // We do this so we can unmarshal from our data-store per-request *without

    // the package user having to do so manually* in the HTTP middleware. We can't

    // rely on the user passing in an fresh instance of their User satisfying type.

    userType User

}


func main() {

    // auth is a pointer to avoid copying the struct per-request: although small

    // here, it contains a 32-byte key, options fields, etc. outside of this example.

    var auth = &Auth{key: []byte("abc")}

    local := &LocalUser{"19313", "Matt", time.Now()}


    b, _, _, err := auth.SetUser(local)

    if err != nil {

        log.Fatalf("SetUser: %v", err)

    }


    user, err := auth.GetUser(b)

    if err != nil {

        log.Fatalf("GetUser: %#v", err)

    }


    fmt.Fprintf(os.Stdout, "%v\n", user)


}


翻过高山走不出你
浏览 170回答 2
2回答

开心每一天1111

如果您需要深度复制接口,请将该方法添加到您的接口中。type User interface {  GetID() string  Copy() User}type LocalUser struct {  ID string  Name string  Created time.Time}// Copy receives a copy of LocalUser and returns a pointer to it.func (u LocalUser) Copy() User {  return &u}

眼眸繁星

因为应用程序将解码为 aUser并且 JSON 解码器的参数必须是指针值,所以我们可以假设User值是指针值。鉴于此假设,以下代码可用于为解码创建新的零值:uzero := reflect.New(reflect.TypeOf(u).Elem()).Interface().(User)
随时随地看视频慕课网APP

相关分类

Go
我要回答