我对Swift 4字符串操作的最佳实践有点困惑。
您如何处理以下事项:
let str = "test"
let start = str.index(str.startIndex, offsetBy: 7)
Thread 1: Fatal error: cannot increment beyond endIndex
想象一下,你不知道上面变量'str'的长度。由于'start'不是一个可选值,防止崩溃的最佳做法是什么?
答案 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) {
...
}
。显然,在您的方案中(endIndex
,if 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)
时间成本,然后您可以以最快的速度对字符数组执行操作。这种方法的缺点是它将内存需求增加一倍以上。