这是代码:
1-offsetBy 为 4 或更少时就可以了
let someString = "hello"
if let someIndex = someString.index(someString.startIndex,
offsetBy: 4, limitedBy: someString.endIndex){
someString[someIndex]
}
// Prints "o"
Run Code Online (Sandbox Code Playgroud)
2- 当 offsetBy 为 6 或更大时就可以了
if let someIndex = someString.index(someString.startIndex,
offsetBy: 6, limitedBy: someString.endIndex){
someString[someIndex]
}
// Prints "nil"
Run Code Online (Sandbox Code Playgroud)
3-但是当offsetBy为5时它会出错
if let someIndex = someString.index(someString.startIndex,
offsetBy: 5, limitedBy: someString.endIndex){
someString[someIndex]
}
// error
Run Code Online (Sandbox Code Playgroud)
错误是:
错误:Playground 执行中止:错误:执行被中断,原因:EXC_BAD_INSTRUCTION(代码=EXC_I386_INVOP,子代码=0x0)。进程已留在中断点,使用“thread return -x”返回到表达式求值之前的状态。
问题在于给定的限制index(_:offsetBy:limitedBy:)是结果的包含范围。因此与
let someString = "hello"
Run Code Online (Sandbox Code Playgroud)
返回的索引
someString.index(someString.startIndex, offsetBy: 5, limitedBy: someString.endIndex)
Run Code Online (Sandbox Code Playgroud)
will be 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])
}
Run Code Online (Sandbox Code Playgroud)
或者更好的选择是使用CharacterViewsindices属性来获取有效索引的集合,以使用(不包括endIndex)下标,并使用dropFirst(_:)andfirst来获取给定偏移处的索引:
if let index = someString.characters.indices.dropFirst(offset).first {
print(someString[index])
}
Run Code Online (Sandbox Code Playgroud)
这利用了以下事实:dropFirst(_:)需要删除元素的上限,如果大于集合的计数,则返回空子序列,以及first返回nil空集合的事实。
| 归档时间: |
|
| 查看次数: |
476 次 |
| 最近记录: |