douxie7738 2019-02-05 10:34 采纳率: 0%
浏览 27
已采纳

当Json解组后,当另一个包访问时Struct为空

I'm am using a struct Contact that has a Load() method. The idea is that Load() populates Contact's fields with data. The data is unmarshalled from json returned by a server. Once loaded, I want to be able to access the data on Contact.

I know that the json is unmarshalling correctly because I can print the data to the console within Load(), immediately after it has been unmarshalled. However, this data is not present on Contact once it has been loaded. So when I create a new Contact and call its Load() method, its data fields are still empty when I go to access them.

This is a simplified version of my code (minus imports for brevity):

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")
}
  • 写回答

1条回答 默认 最新

  • dtj2ww9500 2019-02-05 10:37
    关注

    Contact.Load() modifies the struct, so in order to retain the changes, it must have a pointer receiver:

    func (contact *Contact) Load() error {
        // ...
    }
    

    All parameters (including the receiver) are passed by value which means a copy is made and the functions / methods can only operate on the copy. If the receiver is not a pointer then all changes the method makes are on the copy which is discarded when the method returns.

    If the receiver is a pointer, it will also be copied, but you don't want to modify the pointer but the pointed value, which will be the same.

    See related / possible duplicates:

    My object is not updated even if I use the pointer to a type to update it

    Remove an element of a slice in a struct

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 HLs设计手写数字识别程序编译通不过
  • ¥15 Stata外部命令安装问题求帮助!
  • ¥15 从键盘随机输入A-H中的一串字符串,用七段数码管方法进行绘制。提交代码及运行截图。
  • ¥15 TYPCE母转母,插入认方向
  • ¥15 如何用python向钉钉机器人发送可以放大的图片?
  • ¥15 matlab(相关搜索:紧聚焦)
  • ¥15 基于51单片机的厨房煤气泄露检测报警系统设计
  • ¥15 Arduino无法同时连接多个hx711模块,如何解决?
  • ¥50 需求一个up主付费课程
  • ¥20 模型在y分布之外的数据上预测能力不好如何解决