GoLang,切片读取错误
Posted
技术标签:
【中文标题】GoLang,切片读取错误【英文标题】:GoLang, bad readout from slice 【发布时间】:2018-09-09 11:41:20 【问题描述】:我是 GoLang 的新手,我需要一些帮助。我正在制作简单的 API 应用程序。
通过 API 将结构传递给切片如下所示:
type Struct struct
//some records
var structs []Struct //slice
func SetStruct(w http.ResponseWriter, req *http.Request)
var st Struct
decoder := json.NewDecoder(req.Body)
decoder.Decode(&st)
emails = append(structs, st)
json.NewEncoder(w).Encode(structs)
并且该功能可以正常工作。
我想做的第二件事是从切片中删除该结构取决于NR
参数。我称之为POST
。方法如下:
func SendStruct(w http.ResponseWriter, req *http.Request)
var st Email
decoder := json.NewDecoder(req.Body)
decoder.Decode(&st)
for i, item := range emails
if item.NR == st.NR
structs = append(structs[:i], structs[i+1:]...)
//if numbers match, delete from slice emails
json.NewEncoder(w).Encode(emails)
当我有这样的场景时它工作得很好(例如):
"NR": "22"
"NR": "33"
"NR": "22"
当我想删除"33"
时,它工作得很好。当我想删除"22"
(两者)时,事情开始变得复杂,因为当我通过22
时,应用程序崩溃了。
在item.NR
(来自SendStruct
)中,我的变量超出范围。当我在for
中添加break
参数时,它可以正常工作,但我只能一个接一个地删除结构。我想在一次 API 调用中删除所有 22
。我得到的错误:
http:panic serving [::1]:52163:运行时错误:切片超出范围
感谢您的任何建议!
【问题讨论】:
【参考方案1】:在迭代切片时不应修改切片。 range
不知道切片现在比它开始时短,所以最终它会尝试迭代超过那个点 - 哎呀! -- 找不到更多切片了。
我建议做的是保留一个单独的切片,其中包含可以找到要删除的项目的索引列表。然后,当您完成对电子邮件切片的迭代后,您可以迭代此索引跟踪器切片并删除相关项目。确保您对索引跟踪器切片进行排序,使其从高索引变为低索引,否则您最终将相对于剩余索引点的位置缩短切片。
【讨论】:
我明白了,所以当(例如)我在数组中有 5 个结构时,我删除了第三个,它离开了范围,因为它试图进入第五个但在删除第三个之后,切片是范围是 4 而不是 5? @michasacuer 完全正确。 另一种选择是使用 3 部分 for 循环样式for i := 0; i < len(data); i++
。每次迭代都会检查 Len,从而捕获更新的索引。话虽如此,在迭代时更改切片实际上并不是破坏代码的原因。您正在迭代切片emails
,但使用索引变量来索引和子切片structs
。只要你只从structs
中删减一件事,这就能正常工作,但是一旦你删减了不止一个(并且在最后),你的电子邮件切片现在比结构和恐慌更长。
以上是关于GoLang,切片读取错误的主要内容,如果未能解决你的问题,请参考以下文章