我是Go的新手.我已经读过Go中的封装是在包级别上.我有一个简单的Web控制器用例.我有一个作为 JSON对象进入的结构,并且在结构类型中是Unmarshaled. type User struct{ Name String `json:"name"` //Oth
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()) } }
➜ user git:(master) ✗ go test github.com/teris-io/user
ok github.com/teris-io/user 0.001s
您也可以在解组后将包本地对象转换为某个公共对象.
注意:其中一条评论提到了由于名称冲突(结构上的字段user.Name和接口上的方法User.Name)而导致的可怜程度,接口需要具有不同的方法名称.这不是必需的,并且相应地修改了上面的代码:内部结构上的字段可以具有与JSON中的字段不同的名称,相应的注释定义映射.