Swift 中的String
在過去幾年時(shí)間里面學(xué)習(xí)了好幾門語言,他們分別是:
- Swift1.0
- Swift2.0
- Swift3.0
- Swift4.0
- Swift5.0
好了 現(xiàn)在終于不用學(xué)那么多了吮蛹,又來一個(gè)SwiftUI
在這么多語言中 String變了好幾回米诉,每次用的時(shí)候都要去現(xiàn)查,現(xiàn)在是怎么使用的。很煩人迫肖,現(xiàn)在來研究一下為什么一直在變景醇,為什么不用int 類型下標(biāo)、還有一堆亂七八糟的問題崭闲。
1. 為什么不用int 類型下標(biāo)
String 使用UTF-8編碼肋联,每個(gè)字符由1 - 4個(gè)UTF - 8編碼單位組成,所以字符串的長度就不是固定刁俭,所以如果使用 int 下標(biāo)要先遍歷字符串獲取長度橄仍。
# 假設(shè) String 以 Int 為 index
let hello = "hello"
for i in 0...hello.count{
print(hello[i])
}
# 時(shí)間復(fù)雜度為 O(n^2)
# O(1) + O(2) + O(3) + ... + O(n) = O(n!) ≈ O(n^2)
由此進(jìn)行改進(jìn):
使用偏移量來迭代
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)
}
// 時(shí)間復(fù)雜度為 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不是規(guī)律的,偏移量每次都不一樣
所以引出了下一個(gè)問題
2. 為什么都要用實(shí)例方法
同一個(gè)字符串每個(gè)字符之間的偏移都不同,那么不同字符串呢侮繁,比如:我用字符串A的偏移量虑粥,來迭代字符串B會有什么情況
let strA = "垃圾Swift"
// 從開始便宜兩個(gè)單位
let index = strA.index(strA.startIndex, offsetBy: 2)
print(strA[index])
> S
let strB = "Object-c"
print(strB[index])
> -
使用同一個(gè)index在不同字符串之間,取到的字符不是我們想要的 j
要是我offset 再大一點(diǎn)(比如調(diào)整成 5 )就報(bào)錯(cuò)了
Fatal error: String index is out of bounds: file Swift/StringRangeReplaceableCollection.swift, line 302
3. 為什么要支持不等長的元素宪哩,和其他語言一樣不好嗎娩贷?
如果collection 不支持不等長的元素和其他語言一樣,那就非常簡單了锁孟,String這種類型單獨(dú)處理一下就好了育勺。
swift1.0 時(shí) String 遵循 Collection 協(xié)議
swift2 - 3 時(shí) 移除了這個(gè) conformance
swift 4 又改回去了。 真是日了狗B掎涧至!Swift 更傾向于 API 的正確性,而不是易用性桑包,所以 全部上Index