为了账号安全,请及时绑定邮箱和手机立即绑定

使用指针编辑结构列表变量在go中没有按预期工作

使用指针编辑结构列表变量在go中没有按预期工作

Go
牛魔王的故事 2022-01-17 18:20:24
我有一个看起来像的结构type Request struct {    Name string `json:"name"`    Parameters []Parameter `json:"parameters"`}和type Parameter struct {    Attached bool `json:"attached"`    Script string `json:"script"`}现在,我已将 json 解组到结构中,并且 Script 变量有一个 http 位置“ http://localhost/helloworld.sh ”。我想要做的是,用脚本的实际内容更改 struct 变量Parameter.Script,http://localhost/helloworld.sh这是一个普通的 ascii shell 脚本。我为内部结构写了一个方法,比如func (p *Parameter) SetScript(script string)  {    p.Script = script}使用指向的指针Parameter,并在GetScript函数中,尝试在获取响应正文后调用该方法。func GetScript(params *Request)  {  for _, i := range params.Parameters {    switch i.Attached {    case false:        client := new(http.Client)        req, _ := http.NewRequest("GET", i.Script, nil)        resp, _ := client.Do(req)        defer resp.Body.Close()        reader, _ := ioutil.ReadAll(resp.Body)        i.SetScript(string(reader))    }  }}但是,当我在调用此函数后打印结构时,它并没有修改变量,而是打印http://localhost/helloworld.sh唯一的。我能够获得响应正文,这是脚本的实际内容,但我无法从GetScript函数中替换 struct 变量。有人可以指出正确的方法吗?谢谢你。
查看完整描述

1 回答

?
慕妹3242003

TA贡献1824条经验 获得超6个赞

问题是您正在使用for _, i := range循环,并且您在循环内修改了循环变量:


for _, i := range params.Parameters {

    switch i.Attached {

    case false:

        // ...

        i.SetScript(string(reader))

    }

}

循环变量i是您范围内的切片元素的副本。因此,如果您对其进行任何修改,您只会修改副本,而不是切片中的元素。(请注意,该SetScript()方法确实有一个指针接收器,但它会接收副本的地址,因此它可以并且只会修改副本。)


一种解决方法是使用 index-only range,并使用索引引用切片元素(将所有出现的地方替换为i)params.Parameters[i]:


for i := range params.Parameters {

    switch params.Parameters[i].Attached {

    case false:

        // ...

        params.Parameters[i].SetScript(string(reader))

    }

}

您可以通过将切片分配给局部变量来简化上面的代码(这将只复制切片头而不是其元素,并且它将引用相同的底层数组),并使用if语句而不是那个丑陋的switch:


p := params.Parameters

for i := range p {

    if !p[i].Attached {

        // ...

        p[i].SetScript(string(reader))

    }

}

另一种简化/改进是获取索引表达式的地址,并使用它(因此您可以省略多次重复):


for i := range params.Parameters {

    p := &params.Parameters[i]

    if !p.Attached {

        // ...

        p.SetScript(string(reader))

    }

}


查看完整回答
反对 回复 2022-01-17
  • 1 回答
  • 0 关注
  • 144 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号