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

Dav*_*idR 1 json struct go unmarshalling

我正在使用Contact具有Load()方法的结构.这个想法是用数据Load()填充Contact字段.数据从服务器返回的json中解组.加载后,我希望能够访问数据Contact.

我知道json正确解组,因为我可以Load()在解组后立即将数据打印到控制台内.但是,此数据Contact一旦加载就不存在.所以当我创建一个new 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")
}
Run Code Online (Sandbox Code Playgroud)

icz*_*cza 7

Contact.Load() 修改结构,所以为了保留更改,它必须有一个指针接收器:

func (contact *Contact) Load() error {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

所有参数(包括接收器)都通过值传递,这意味着复制并且功能/方法只能在副本上运行.如果接收器不是指针,那么方法所做的所有更改都是在方法返回时丢弃的副本上.

如果接收器是一个指针,它也将被复制,但你不想修改指针但指向的值,这将是相同的.

查看相关/可能重复:

即使我使用指向类型的指针来更新它,我的对象也不会更新

删除结构中切片的元素