首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Go中封装结构

在Go中封装结构
EN

Stack Overflow用户
提问于 2018-03-06 08:54:15
回答 1查看 2.8K关注 0票数 7

我是新来的。我读过Go中的封装是在包级别上的。我有一个简单的网络控制器用例。我有一个结构,它以JSON对象的形式出现,并被解封为struct类型。

代码语言:javascript
复制
type User struct{
    Name String `json:"name"`
    //Other Variables
}

现在,可以通过json.Unmarshal([]字节)将json解封为用户结构类型。但是,此用户结构也可用于其他包。如何确保只有与用户相关的方法才能被其他包访问。

我能想到的一个解决方案是:

代码语言:javascript
复制
type User struct{
    name String
}

type UserJSON struct{
    Name String `json:"name"`
}

func DecodeJSONToUser(rawJSON []byte) (User,error) {
    var userJSON UserJSON
    err := json.Unmarshal(rawJSON,&userJSON)
    //Do error handling
    return User{name:userJSON.Name},nil
}

有什么GOish方法可以实现这一点吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-03-06 09:17:32

可以使用包本地结构公共字段,使此结构在包外不可见。然后,您可以使这个结构满足一些公共接口,并且您有了完美的解耦:

代码语言:javascript
复制
package user

import "encoding/json"

type User interface {
    Name() string
}

type user struct {
    Username string `json:"name"`
}

func (u *user) Name() string {
    return "Mr. " + u.Username
}

func ParseUserData(data []byte) (User, error) {
    user := &user{}
    if err := json.Unmarshal(data, user); err != nil {
        return nil, err
    }
    return user, nil
}

以及相应的测试:

代码语言:javascript
复制
package user_test

import (
    "testing"

    "github.com/teris-io/user"
)

func TestParseUserData(t *testing.T) {
    data := []byte("{\"name\": \"Uncle Sam\"}")
    expected := "Mr. Uncle Sam"
    if usr, err := user.ParseUserData(data); err != nil {
        t.Fatal(err.Error())
    } else if usr.Name() != expected {
        t.Fatalf("expected %s, found %s", expected, usr.Name())
    }
}

➜用户git:(主)✗go测试github.com/teris-io/user ok github.com/teris-io/user 0.001

您还可以在解封送处理之后将包本地对象转换为某些公共对象。

Note:其中一条评论提到,由于名称冲突(结构上的字段user.Name,接口上的方法User.Name ),接口需要有不同的方法名,这是多么遗憾。这是不必要的,上面的代码也进行了相应的修改:内部结构上的字段可以有与JSON中不同的名称,相应的注释定义映射。

票数 13
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49126784

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档