[英]Editing a struct list variable using pointer not working as expected in go
我有一个看起来像的结构
type Request struct {
Name string `json:"name"`
Parameters []Parameter `json:"parameters"`
}
和
type Parameter struct {
Attached bool `json:"attached"`
Script string `json:"script"`
}
现在,我已经将json解组到struct中,而Script变量的http位置为“ http://localhost/helloworld.sh ”。 我想要做的是,从http://localhost/helloworld.sh
更改结构变量Parameter.Script
与脚本的实际内容,这是一个简单的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变量。 有人可以指出正确的方法吗?
谢谢。
问题是你正在使用for _, i := range
循环,并修改循环内的循环变量:
for _, i := range params.Parameters {
switch i.Attached {
case false:
// ...
i.SetScript(string(reader))
}
}
循环变量i
是您定位的切片元素的副本 。 因此,如果对其进行任何修改,则只会修改副本而不是切片中的元素。 (注意, SetScript()
方法确实有一个指针接收器,但是它会接收副本的地址,因此它可以并且只会修改副本。)
一种解决方法是使用仅索引range
,并使用索引引用切片元素(用params.Parameters[i]
替换所有出现的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 := ¶ms.Parameters[i]
if !p.Attached {
// ...
p.SetScript(string(reader))
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.