Swift中Index out of bounds错误排查及两类索引错误区别咨询
Index out of bounds 报错分析及问题解答
一、"Index out of bounds" 与 "Index out of range" 的区别
这两个表述本质是同一个错误的不同说法,核心都是访问了集合(数组、切片等)不存在的索引:
- Index out of bounds:Swift 官方的报错提示,指索引超出了集合的有效边界
- Index out of range:Python、Java等其他编程语言的常用表述,含义完全一致,都是索引不在集合允许的索引区间内
二、代码报错原因排查
结合你的代码和输入拆解问题:
输入与原数组情况
你的输入包含21个元素:
1 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919
转换后input数组的有效索引范围是0...20。
切片的索引特性是核心问题
你执行var arr = input[1...20]时,得到的不是新数组,而是原数组的切片(Slice)。Swift的切片有个关键特性:它的索引继承自原数组,不会重新从0开始编号。
也就是说,arr这个切片的有效索引是1...20,而非你以为的0...19。你用enumerated()遍历的时候,enumerated()只是给每个元素分配了从0开始的序列编号,但这个编号不等于切片的实际索引——切片本身的索引还是原数组的1到20。
所以当你执行print(arr[0])时,你试图访问切片不存在的0索引,直接触发了Index out of bounds错误。
输出验证
从你的遍历输出也能佐证这一点:enumerated()给出的i是0到19,但对应的元素是原数组索引1到20的内容,i只是遍历的序号,不是切片的实际索引。
三、修正方案
有两种常见的修正方式:
方式1:将切片转为新数组
如果需要得到一个从0开始索引的新数组,把切片转换为数组即可:
var input = readLine()!.split(separator: " ").map{Int($0)!} // 把切片转为数组,新数组索引从0开始 var arr = Array(input[1...20]) for (i, a) in arr.enumerated() { print(i, a) } print(arr[0]) // 正常输出900
方式2:使用切片的实际索引访问
如果要保留切片,必须用它的有效索引访问元素:
var input = readLine()!.split(separator: " ").map{Int($0)!} var arr = input[1...20] for (i, a) in arr.enumerated() { print(i, a) } print(arr[1]) // 输出900,对应切片的起始有效索引
内容的提问来源于stack exchange,提问作者jpatrick
相关产品推荐
相关产品推荐

