我正在使用具有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")
}
答案 0 :(得分:7)
Contact.Load()
修改了结构,因此为了保留更改,它必须具有指针接收器:
func (contact *Contact) Load() error {
// ...
}
所有参数(包括接收器)均按值传递,这意味着将进行复制,并且功能/方法只能在该复制上操作。如果接收方不是指针,则该方法所做的所有更改都在副本上,该副本在方法返回时被丢弃。
如果接收方是指针,则它也将被复制,但是您不想修改指针,而要修改指向的值,这将是相同的。
查看相关的/可能的重复项:
My object is not updated even if I use the pointer to a type to update it