Swift 4子串崩溃

时间:2017-12-10 16:36:51

标签: swift

我对Swift 4字符串操作的最佳实践有点困惑。

您如何处理以下事项:

let str = "test"
let start = str.index(str.startIndex, offsetBy: 7)


Thread 1: Fatal error: cannot increment beyond endIndex

想象一下,你不知道上面变量'str'的长度。由于'start'不是一个可选值,防止崩溃的最佳做法是什么?

2 个答案:

答案 0 :(得分:4)

如果您使用带static bool IsMethodImplementationOfInterface(Type interfaceType,MethodInfo method) { return method.ReflectedType.GetInterfaceMap(interfaceType).TargetMethods.Contains(method); } foreach (var methodInfo in typeof(TestImpl).GetMethods()) { if (IsMethodImplementationOfInterface(typeof(ITest), methodInfo)) { //Logic } } 参数的变体,则会返回一个可选值:

limitedBy

这将优雅地检测偏移是否使索引移过if let start = str.index(str.startIndex, offsetBy: 7, limitedBy: str.endIndex) { ... } 。显然,在您的方案中(endIndexif let,nil coalescing operator等)最好处理此选项。

答案 1 :(得分:1)

您的代码没有进行任何范围检查:

let str = "test"
let start = str.index(str.startIndex, offsetBy: 7)

编写一个首先测试字符串长度的函数。实际上,您可以在String上创建一个扩展,允许您使用整数下标,并返回Character?

extension String {
  //Allow string[Int] subscripting
  subscript(index: Int) -> Character? {
    guard index < self.count else { return nil }
    return self[self.index(self.startIndex, offsetBy: index)]
  }
}

此代码:

var str = "test"
print("str[7] = \"\(str[7])\"")

会显示:

str[7] = "nil"

编辑:

请注意,正如亚历山大在下面的评论中指出的那样,上面的下标扩展具有高达O(n)的性能(随着索引值的增加,它需要更长更长的时间,直到字符串的长度。 )

如果你需要遍历字符串代码中的所有字符,如下所示:

for i in str.count { doSomething(string: str[i]) } 

会有O(n^2)(或n-squared)表现,这真的非常糟糕。在这种情况下,您应该首先将字符串转换为字符数组:

 let chars = Array(str.characters)

 for i in chars.count { doSomething(string: chars[i]) } 

 for aChar in chars { //do something with aChar }

使用该代码,您需要支付将{1}}字符串转换为字符数组的O(n)时间成本,然后您可以以最快的速度对字符数组执行操作。这种方法的缺点是它将内存需求增加一倍以上。