在Go中封装结构
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Go中封装结构相关的知识,希望对你有一定的参考价值。
我是Go的新手。我已经读过Go中的封装是在包级别上。我有一个简单的Web控制器用例。我有一个作为JSON对象进入的结构,并且在结构类型中是Unmarshaled。
type User struct{
Name String `json:"name"`
//Other Variables
}
现在可以通过json.Unmarshal([] byte)将json解组为User Struct类型。但是,此User结构也可用于其他包。如何确保其他软件包只能访问与User相关的方法。
我能想到的一个解决方案:
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
}
有没有一种可以实现这一目标的方法?
答案
您可以将包本地结构与公共字段一起使用,以使此结构在包外不可见。然后你可以使这个结构满足一些公共接口,你有完美的解耦:
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
}
并进行相应的测试:
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 :(主)✗去测试github.com/teris-io/user
ok github.com/teris-io/user 0.001s
您也可以在解组后将包本地对象转换为某个公共对象。
注意:其中一条评论提到由于名称冲突(结构上的字段user.Name
和接口上的方法User.Name
),它是多么可怜,接口需要具有不同的方法名称。这不是必需的,并且相应地修改了上面的代码:内部结构上的字段可以具有与JSON中的字段不同的名称,相应的注释定义映射。
以上是关于在Go中封装结构的主要内容,如果未能解决你的问题,请参考以下文章