为什么当我在index(u,offsetBy,limitedBy)函数中将offsetBy值设置为等于endIndex值时,swift会给出一个错误?

为什么当我在index(u,offsetBy,limitedBy)函数中将offsetBy值设置为等于endIndex值时,swift会给出一个错误?,swift,Swift,代码如下: 1-当补偿为4或更少时,这是正常的 let someString = "hello" if let someIndex = someString.index(someString.startIndex, offsetBy: 4, limitedBy: someString.endIndex){ someString[someIndex] } // Prints "o" 2-当补偿为6或

代码如下:

1-当补偿为4或更少时,这是正常的

    let someString = "hello"

    if let someIndex = someString.index(someString.startIndex, 
                        offsetBy: 4, limitedBy: someString.endIndex){
       someString[someIndex]
    }
    // Prints "o"
2-当补偿为6或更大时,这是正常的

    if let someIndex = someString.index(someString.startIndex, 
                        offsetBy: 6, limitedBy: someString.endIndex){
       someString[someIndex]
    }
    // Prints "nil"
3-但当偏移量为5时,它会给出错误

    if let someIndex = someString.index(someString.startIndex, 
                        offsetBy: 5, limitedBy: someString.endIndex){
       someString[someIndex]
    }
    // error
错误是:

错误:执行中止:错误:执行被中断, 原因:EXC_错误指令(代码=EXC_I386_INVOP,子代码=0x0)。这个 进程被留在中断的位置,请使用 “thread return-x”返回到表达式之前的状态 评估


问题在于,给
索引(u:offsetBy:limitedBy:)
的限制是结果的包含边界。因此

let someString = "hello"
由返回的索引

someString.index(someString.startIndex, offsetBy: 5, limitedBy: someString.endIndex)
将是
someString.endIndex
,它是结束索引之后的索引,因此不是用于为字符串下标的有效索引

因此,一个简单的解决方案是只需在
if
语句中添加一个条件,以检查返回的索引是否不是
endIndex

let someString = "hello"
let offset = 5

if let someIndex = someString.index(someString.startIndex,
                                    offsetBy: offset,
                                    limitedBy: someString.endIndex
                                    ), someIndex != someString.endIndex {
    print(someString[someIndex])
}
或者更好的选择是使用
CharacterView
的属性来获取要下标的有效索引集合(不包括
endIndex
),并使用和来获取给定偏移处的索引:

if let index = someString.characters.indices.dropFirst(offset).first {
    print(someString[index])
}

这利用了
dropFirst(:)
接受要删除的元素的上限,如果大于集合的计数,则返回空的子序列,以及
first
为空集合返回
nil
这一事实。

比较您使用的限制值是错误的<代码>结束索引超过最后一个有效索引。相反,请使用
limitedBy:str.index(在:str.endIndex之前)
@Hamish谢谢。我读了链接。但受到6级或更高限值的限制。为什么不是5?或者:
如果让someIndex=someString.index(someString.startIndex,offsetBy:5,limitedBy:someString.endIndex),someIndex!=someString.endIndex{…}
–请注意
str.index(之前:str.endIndex
将因空字符串而失败。@Arashk因为
endIndex
仍然是一个有用的索引–在形成范围
someIndex时最常用。@Downvoter我尊重您的匿名权,但欢迎任何建设性的反馈。我对我的答案的质量感到自豪,并一直希望改进我的答案。)(请告诉他们:)