Golang对n个切片值求和时出现索引越界运行时错误排查
错误原因
你最初怀疑的float32类型问题不成立,触发index out of range [0] with length 0 panic的核心原因是切片初始化逻辑错误:
- 你写的
scores := []uint{}会创建一个长度为0、容量为0的空切片,这个切片不存在任何可访问的索引位置 - 循环第一次执行时
i=0,你尝试访问scores[0],相当于在长度为0的切片上取第0位元素,直接触发索引越界崩溃,和你使用的数值类型没有任何关系。
修复方案
提供两种可正常运行的实现方式:
方案1:预分配固定长度切片(推荐,已知元素个数场景性能更好)
提前拿到用户输入的分数个数n后,用make函数初始化长度为n的切片,此时0~n-1的索引位置都是合法可访问的,同时增加n的合法性校验避免除零错误:
package main import "fmt" func main() { var n int var sumScores float32 = 0 fmt.Println("How many scores?") fmt.Scan(&n) // 校验输入的个数合法性 if n <= 0 { fmt.Println("Error: score count must be greater than 0") return } // 初始化长度为n的切片 scores := make([]uint, n) for i := 0; i < n; i++ { fmt.Printf("Scores: ") fmt.Scan(&scores[i]) sumScores += float32(scores[i]) } fmt.Printf("Average: %f\n", sumScores/float32(n)) }
方案2:动态追加元素(适合未知最终元素个数的场景)
不提前固定切片长度,每次读入分数后用append把值追加到切片末尾:
package main import "fmt" func main() { var n int scores := []uint{} var sumScores float32 = 0 fmt.Println("How many scores?") fmt.Scan(&n) if n <= 0 { fmt.Println("Error: score count must be greater than 0") return } for i := 0; i < n; i++ { fmt.Printf("Scores: ") var tmp uint fmt.Scan(&tmp) scores = append(scores, tmp) sumScores += float32(tmp) } fmt.Printf("Average: %f\n", sumScores/float32(n)) }
注意事项
- Go中长度为0的空切片不能直接通过索引赋值,要么通过
make预分配对应长度的内存空间,要么通过append动态扩容追加元素 - 遇到
index out of range类panic时,优先检查访问的索引值是否超出了切片/数组当前的实际长度,和元素存储类型无关
内容的提问来源于stack exchange,提问作者Migue
相关产品推荐
相关产品推荐

