json - 当被另一个包访问时,结构在 Json 解组后为空
问题描述
我正在使用Contact
具有Load()
方法的结构。这个想法是用数据Load()
填充Contact
的字段。数据从服务器返回的 json 中解组。加载后,我希望能够访问Contact
.
我知道 json 正在正确解组,因为我可以在Load()
解组后立即将数据打印到控制台。Contact
但是,一旦加载,此数据就不会出现。所以当我创建一个新的Contact
并调用它的Load()
方法时,当我去访问它们时,它的数据字段仍然是空的。
这是我的代码的简化版本(为简洁起见减去导入):
package main
func main() {
client := &http.Client{}
mp := myPackage.NewContact("1234", client)
if err := mp.Load(); err != nil {
log.Println(err)
}
// prints empty string
log.Println(mp.EmailOptIn)
}
// myPackage
package myPackage
type Contact struct {
ID string
client *http.Client
EmailOptIn string `json:"marketing_optin"`
}
func NewContact(ID string, client *http.Client) *Contact {
return &Contact{
ID: ID,
client: client,
}
}
func (contact Contact) Load() error {
req, err := http.NewRequest("GET", "https://anAPI.com/"+contact.ID, nil)
if err != nil {
log.Println(err)
}
resp, err := contact.client.Do(req)
if err != nil {
log.Println(err)
}
defer resp.Body.Close()
if resp.StatusCode == 200 {
body, _ := ioutil.ReadAll(resp.Body)
if err = json.Unmarshal(body, &contact); err != nil {
log.Println("Can't unmarshall: " + err.Error())
}
// prints "Opted_in"
log.Println(contact.EmailOptIn)
return nil
}
return errors.New("oh dear")
}
解决方案
Contact.Load()
修改结构,因此为了保留更改,它必须有一个指针接收器:
func (contact *Contact) Load() error {
// ...
}
所有参数(包括接收者)都是按值传递的,这意味着制作了一个副本,并且函数/方法只能对副本进行操作。如果接收者不是指针,那么方法所做的所有更改都在方法返回时丢弃的副本上。
如果接收者是一个指针,它也会被复制,但是你不想修改指针而是修改指向的值,这将是相同的。
查看相关/可能的重复项:
推荐阅读
- java - Apache Beam GroupByKey 使用 PubSubIO 输出重复元素
- python - 循环遍历字典的 1 级 + 3 级
- processing - 为什么我在处理中制作棋盘的代码不起作用?
- node.js - 使用 pug 模板尝试 axios 时遇到问题
- javascript - Javascript所有按钮都没有被点击
- c# - Automapper - 作为子嵌套时忽略属性
- mysql - 基于一列值连接 SQL 表中的多行
- go - cobra PersistentPreRun 堆栈溢出
- mongodb - 验证参考字段是否为空不在月光中工作
- python - 并非所有 Python 代码都在 AWS Lambda 函数中执行