swift String

2020-11-02  本文已影响0人  等这姑娘老在我心里

Swift 中的String

在过去几年时间里面学习了好几门语言,他们分别是:

好了 现在终于不用学那么多了,又来一个SwiftUI

在这么多语言中 String变了好几回,每次用的时候都要去现查,现在是怎么使用的。很烦人,现在来研究一下为什么一直在变,为什么不用int 类型下标、还有一堆乱七八糟的问题。

1. 为什么不用int 类型下标

String 使用UTF-8编码,每个字符由1 - 4UTF - 8编码单位组成,所以字符串的长度就不是固定,所以如果使用 int 下标要先遍历字符串获取长度。

# 假设 String 以 Int 为 index
let hello = "hello"
for i in 0...hello.count{
    print(hello[i])
}
# 时间复杂度为 O(n^2)
# O(1) + O(2) + O(3) + ... + O(n) = O(n!) ≈ O(n^2)

由此进行改进:

使用偏移量来迭代

let hello = "hello"
/// String.Index 类型
var index = hello.startIndex

while index != hello.endIndex{
        print(hello[index])
      print(hello.index(after: index))
      index = hello.index(after: index)
}
// 时间复杂度为 O(n)
// O(1) + O(1) + O(1) + ... + O(1) = O(n) 

Index(_rawBits: 65793)
Index(_rawBits: 131329)
Index(_rawBits: 196865)
Index(_rawBits: 262401)
Index(_rawBits: 327681)

但是我们可以看到index不是规律的,偏移量每次都不一样

所以引出了下一个问题

2. 为什么都要用实例方法

同一个字符串每个字符之间的偏移都不同,那么不同字符串呢,比如:我用字符串A的偏移量,来迭代字符串B会有什么情况

let strA = "垃圾Swift"
// 从开始便宜两个单位
let index = strA.index(strA.startIndex, offsetBy: 2)
print(strA[index])
> S

let strB = "Object-c"
print(strB[index])
> -

使用同一个index在不同字符串之间,取到的字符不是我们想要的 j

要是我offset 再大一点(比如调整成 5 )就报错了

Fatal error: String index is out of bounds: file Swift/StringRangeReplaceableCollection.swift, line 302

3. 为什么要支持不等长的元素,和其他语言一样不好吗?

如果collection 不支持不等长的元素和其他语言一样,那就非常简单了,String这种类型单独处理一下就好了。

swift1.0 时 String 遵循 Collection 协议

swift2 - 3 时 移除了这个 conformance

swift 4 又改回去了。 真是日了狗!! 狗头

Swift 更倾向于 API 的正确性,而不是易用性,所以 全部上Index

上一篇下一篇

猜你喜欢

热点阅读