1疙剑,因為 Swift 是類型安全的氯迂,他在編譯代碼的時候會進(jìn)行類型檢查,任何不匹配的類型都會被標(biāo)記為錯誤言缤。這會幫助你在開發(fā)階段更早的發(fā)現(xiàn)并修復(fù)錯誤嚼蚀;
2,Swift 在推斷浮點值的時候始終會選擇 Double (而不是 Float )
3管挟,Swift 中的 nil 和Objective-C 中的 nil 不同轿曙,在 Objective-C 中 nil 是一個指向不存在對象的指針。在 Swift中僻孝, nil 不是指針导帝,他是值缺失的一種特殊類型,任何類型的可選項都可以設(shè)置成 nil 而不僅僅是對象類型
4穿铆,與 Objective-C 和 C 不同您单,Swift 的賦值符號自身不會返回值。下面的語句是不合法的:
5荞雏,if x = y { // 這是不合法的, 因為 x = y 并不會返回任何值虐秦。}
6,對a % b 與 a % -b 讯檐,當(dāng) b為負(fù)數(shù)時羡疗,它的正負(fù)號會被忽略掉。這意味著 a % b 與 a % -b 能夠獲得相同的答案别洪,也就是說余數(shù)的正負(fù)是與被除數(shù)的正負(fù)有關(guān)
7叨恨,Swift 標(biāo)準(zhǔn)庫包含的元組比較運算符僅支持小于七個元素的元組。要比較擁有七個或者更多元素的元組挖垛,你必須自己實現(xiàn)比較運算符
8痒钝,閉區(qū)間有另外一種形式來讓區(qū)間朝一個方向盡可能的遠(yuǎn)——比如說,一個包含數(shù)組所有元素的區(qū)間痢毒,從索引 2 到數(shù)組的結(jié)束送矩。在這種情況下,你可以省略區(qū)間運算符一側(cè)的值哪替。因為運算符只有一側(cè)有值栋荸,所以這種區(qū)間叫做單側(cè)區(qū)間。比如說:
for name in names[2...] ?{ print(name) }
9,Swift 的 String 和 Character 類型提供了一種快速的符合 Unicode 的方式操作你的代碼晌块,Swift 的 String類型仍舊是快速和現(xiàn)代的字符串實現(xiàn)爱沟。每一個字符串都是由 Unicode 字符的獨立編碼組成,并且提供了多種 Unicode 表示下訪問這些字符的支持匆背,Swift 的 String類型橋接到了基礎(chǔ)庫中的 NSString類呼伸。Foundation 同時也擴(kuò)展了所有 NSString 定義的方法給 String 。也就是說钝尸,如果你導(dǎo)入 Foundation 括享,就可以在 String 中訪問所有的 NSString 方法,無需轉(zhuǎn)換格式珍促。
10铃辖,Swift 的 String類型是一種值類型每一次賦值和傳遞,現(xiàn)存的 String值都會被復(fù)制一次踢星,傳遞走的是拷貝而不是原本澳叉,Swift 的默認(rèn)拷貝 String行為保證了當(dāng)一個方法或者函數(shù)傳給你一個 String值,你就絕對擁有了這個 String值沐悦。
11,Swift 編譯器優(yōu)化了字符串使用的資源五督,實際上拷貝只會在確實需要的時候才進(jìn)行藏否。這意味著當(dāng)你把字符串當(dāng)做值類型來操作的時候總是能夠有用很棒的性能
12,操作字符:你可以通過 for-in循環(huán)遍歷 String 中的每一個獨立的 Character值充包,你不能把 String或者 Character追加到已經(jīng)存在的 Character變量當(dāng)中副签,因為 Character值能且只能包含一個字符。
13基矮,字符統(tǒng)計:在字符串中取回 Character值的總數(shù)淆储,使用字符串的 count屬性,注意 Swift 為 Character值使用的擴(kuò)展字形集群意味著字符串的創(chuàng)建和修改可能不會總是影響字符串的字符統(tǒng)計數(shù)家浇。
14本砰,字符統(tǒng)計:在字符串中取回 Character值的總數(shù),使用字符串的 count屬性钢悲,注意 Swift 為 Character值使用的擴(kuò)展字形集群意味著字符串的創(chuàng)建和修改可能不會總是影響字符串的字符統(tǒng)計數(shù)点额。
15,每一個 String值都有相關(guān)的索引類型莺琳, String.Index还棱,它相當(dāng)于每個 Character在字符串中的位置。
16惭等,不同的字符會獲得不同的內(nèi)存空間來儲存珍手,所以為了明確哪個 Character 在哪個特定的位置,你必須從 String的開頭或結(jié)尾遍歷每一個 Unicode 標(biāo)量。因此琳要,Swift 的字符串不能通過整數(shù)值索引寡具;使用 index(before:) 和 index(after:) 方法來訪問給定索引的前后。要訪問給定索引更遠(yuǎn)的索引焙蹭,你可以使用 index(_:offsetBy:) 方法而不是多次調(diào)用這兩個方法晒杈。
17,嘗試訪問的 Character如果索引位置在字符串范圍之外孔厉,就會觸發(fā)運行時錯誤拯钻。使用 characters屬性的 indices屬性來創(chuàng)建所有能夠用來訪問字符串中獨立字符的索引范圍 Range;
for index in greeting.characters.indices {
? ? print("\(greeting[index]) ", terminator: "")
}
18撰豺,你可以在任何遵循了 Indexable 協(xié)議的類型中使用 startIndex 和 endIndex 屬性以及 index(before:) 粪般, index(after:) 和 index(_:offsetBy:) 方法。這包括這里使用的 String 污桦,還有集合類型比如 Array 亩歹, Dictionary 和 Set。
19凡橱,要移除一小段特定范圍的字符串小作,使用 removeSubrange(_:) 方法:let range = welcome.index(welcome.endIndex, offsetBy: -6)..<welcome.endIndex;
welcome.removeSubrange(range);
20,你可以在任何遵循了 RangeReplaceableIndexable 協(xié)議的類型中使用 insert(_:at:) , insert(contentsOf:at:) 稼钩, remove(at:) 方法顾稀。這包括了這里使用的 String ,同樣還有集合類型比如 Array 坝撑, Dictionary 和 Set 静秆。
21,訪問和修改數(shù)組:使用布爾量 isEmpty屬性來作為檢查 count屬性是否等于 0的快捷方式;
可以使用加賦值運算符 ( +=)來在數(shù)組末尾添加一個或者多個同類型元素:shoppingList += ["Chocolate Spread", "Cheese", "Butter"]
可以使用下標(biāo)腳本語法來一次改變一個范圍的值巡李,就算替換與范圍長度不同的值的合集也行:shoppingList[4...6] = ["Bananas", "Apples"]抚笔。
22,如果你需要每個元素以及值的整數(shù)索引,使用 enumerated()方法來遍歷數(shù)組侨拦。 enumerated()方法返回數(shù)組中每一個元素的元組殊橙,包含了這個元素的索引和值:for (index, value) in shoppingList.enumerated() {
? ? print("Item \(index + 1): \(value)")
}
23,Set合集類型不能從數(shù)組字面量推斷出來,所以 Set類型必須被顯式地聲明阳谍;合集將同一類型且不重復(fù)的值無序地儲存在一個集合當(dāng)中蛀柴。當(dāng)元素的順序不那么重要的時候你就可以使用合集來代替數(shù)組,或者你需要確保元素不會重復(fù)的時候矫夯。
24鸽疾,基本合集操作:
使用 intersection(_:)方法來創(chuàng)建一個只包含兩個合集共有值的新合集;
使用 symmetricDifference(_:)方法來創(chuàng)建一個只包含兩個合集各自有的非共有值的新合集训貌;
使用 union(_:)方法來創(chuàng)建一個包含兩個合集所有值的新合集制肮;
使用 subtracting(_:)方法來創(chuàng)建一個兩個合集當(dāng)中不包含某個合集值的新合集冒窍;
let oddDigits: Set = [1, 3, 5, 7, 9]
let evenDigits: Set = [0, 2, 4, 6, 8]
let singleDigitPrimeNumbers: Set = [2, 3, 5, 7]
oddDigits.union(evenDigits).sorted()
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
oddDigits.intersection(evenDigits).sorted()
// []
oddDigits.subtracting(singleDigitPrimeNumbers).sorted()
// [1, 9]
oddDigits.symmetricDifference(singleDigitPrimeNumbers).sorted()
// [1, 2, 9]
25,使用“相等”運算符 ( == )來判斷兩個合集是否包含有相同的值豺鼻;
使用 isSubset(of:) 方法來確定一個合集的所有值是被某合集包含综液;
使用 isSuperset(of:)方法來確定一個合集是否包含某個合集的所有值;
使用 isStrictSubset(of:) 或者 isStrictSuperset(of:)方法來確定是個合集是否為某一個合集的子集或者超集儒飒,但并不相等谬莹;
使用 isDisjoint(with:)方法來判斷兩個合集是否擁有完全不同的值。
let houseAnimals: Set = ["??", "??"]
let farmAnimals: Set = ["??", "??", "??", "??", "??"]
let cityAnimals: Set = ["??", "??"]
houseAnimals.isSubset(of: farmAnimals)
// true
farmAnimals.isSuperset(of: houseAnimals)
// true
farmAnimals.isDisjoint(with: cityAnimals)
// true
26桩了,字典類型: 可 (以Int類型)為鍵值附帽,例如:var namesOfIntegers = [Int: String]();使用 stride(from:to:by:) 函數(shù)來跳過不想要的標(biāo)記井誉;
let minutes = 60
let minuteInterval = 5
for tickMark in stride(from: 0, to: minutes, by: minuteInterval) {
? ? // render the tick mark every 5 minutes (0, 5, 10, 15 ... 45, 50, 55) ?//【小于60】
}
27,閉區(qū)間也同樣適用蕉扮,使用 stride(from:through:by:) 即可:
let hours = 12
let hourInterval = 3
for tickMark in stride(from: 3, through: hours, by: hourInterval) {
? ? // render the tick mark every 3 hours (3, 6, 9, 12) //可等于12
}
28,switch沒有隱式貫穿:相比 C 和 Objective-C 里的 switch 語句來說颗圣,Swift 里的 switch 語句不會默認(rèn)從每個情況的末尾貫穿到下一個情況里喳钟。相反,整個 switch 語句會在匹配到第一個 switch 情況執(zhí)行完畢之后退出在岂,不再需要顯式的 break 語句奔则。
29,在一個 switch 情況中匹配多個值可以用逗號分隔蔽午,并且可以寫成多行:
let anotherCharacter: Character = "a"
switch anotherCharacter {
case "a", "A":
? ? print("The letter A")
default:
? ? print("Not the letter A")
}
// Prints "The letter A"
30应狱,區(qū)間匹配: case 1..<5
元組:? ?
你可以使用元組來在一個 switch 語句中測試多個值。每個元組中的元素都可以與不同的值或者區(qū)間進(jìn)行匹配祠丝。另外,使用下劃線( _)來表明匹配所有可能的值除嘹;
let somePoint = (1, 1)
switch somePoint {
case (0, 0):
? ? print("(0, 0) is at the origin")
case (_, 0):
? ? print("(\(somePoint.0), 0) is on the x-axis")
case (0, _):
? ? print("(0, \(somePoint.1)) is on the y-axis")
case (-2...2, -2...2):
? ? print("(\(somePoint.0), \(somePoint.1)) is inside the box")
default:
? ? print("(\(somePoint.0), \(somePoint.1)) is outside of the box")
}
31写半,switch 情況可以將匹配到的值臨時綁定為一個常量或者變量,來給情況的函數(shù)體使用尉咕。這就是所謂的值綁定叠蝇,
let anotherPoint = (2, 0)
switch anotherPoint {
case (let x, 0):
? ? print("on the x-axis with an x value of \(x)")
case (0, let y):
? ? print("on the y-axis with a y value of \(y)")
case let (x, y):
? ? print("somewhere else at (\(x), \(y))")
}
32,switch 情況可以使用 where 分句來檢查額外的情況
let yetAnotherPoint = (1, -1)
switch yetAnotherPoint {
case let (x, y) where x == y:
? ? print("(\(x), \(y)) is on the line x == y")
case let (x, y) where x == -y:
? ? print("(\(x), \(y)) is on the line x == -y")
case let (x, y):
? ? print("(\(x), \(y)) is just some arbitrary point")
}
33年缎,復(fù)合情況:
多個 switch 共享同一個函數(shù)體的多個情況可以在 case 后寫多個模式來復(fù)合悔捶,在每個模式之間用逗號分隔。
let someCharacter: Character = "e"
switch someCharacter {
case "a", "e", "i", "o", "u":
? ? print("\(someCharacter) is a vowel")
case "b", "c", "d", "f", "g", "h", "j", "k", "l", "m",
? ? "n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z":
? ? print("\(someCharacter) is a consonant")
default:
? ? print("\(someCharacter) is not a vowel or a consonant")
}
34单芜,復(fù)合情況同樣可以包含值綁定蜕该。所有復(fù)合情況的模式都必須包含相同的值綁定集合,并且復(fù)合情況中的每一個綁定都得有相同的類型格式洲鸠。這才能確保無論復(fù)合情況的那部分匹配了堂淡,接下來的函數(shù)體中的代碼都能訪問到綁定的值并且值的類型也都相同馋缅。
let stillAnotherPoint = (9, 0)
switch stillAnotherPoint {
case (let distance, 0), (0, let distance):
? ? print("On an axis, \(distance) from the origin")
default:
? ? print("Not on an axis")
}
35,控制轉(zhuǎn)移語句有五種:continue绢淀,break萤悴,fallthrough,return皆的,throw覆履;如果你確實需要 C 風(fēng)格的貫穿行為,你可以選擇在每個情況末尾使用 fallthrough 關(guān)鍵字费薄,
let integerToDescribe = 5
var description = "The number \(integerToDescribe) is"
switch integerToDescribe {
case 2, 3, 5, 7, 11, 13, 17, 19:
? ? description += " a prime number, and also"
? ? fallthrough
default:
? ? description += " an integer."
}
它使用 fallthrough 關(guān)鍵字來“貫穿到” default 情況硝全。 default 情況添加額外的文字到描述的末尾,接著 switch 語句結(jié)束义锥;fallthrough 關(guān)鍵字不會為switch情況檢查貫穿入情況的條件柳沙。 fallthrough 關(guān)鍵字只是使代碼執(zhí)行直接移動到下一個情況(或者 default 情況)的代碼塊中,就像C的標(biāo)準(zhǔn) switch 語句行為一樣拌倍。
36赂鲤,guard 語句總是有一個 else 分句—— else 分句里的代碼會在條件不為真的時候執(zhí)行。if #available(iOS 10, macOS 10.12, *) 最后一個實際參數(shù)柱恤, * 数初,它需求并表明在其他所有平臺, if 函數(shù)體執(zhí)行你在目標(biāo)里明確的最小部屬;
37,類似 (Int, Int)?的可選元組類型和包含可選類型的元組 (Int?, Int?)是不同的梗顺。對于可選元組類型泡孩,整個元組是可選的,而不僅僅是元組里邊的單個值寺谤。
38,輸入輸出形式參數(shù):
如果你想函數(shù)能夠修改一個形式參數(shù)的值仑鸥,而且你想這些改變在函數(shù)結(jié)束之后依然生效,那么就需要將形式參數(shù)定義為輸入輸出形式參數(shù)变屁。
在形式參數(shù)定義開始的時候在前邊添加一個 inout關(guān)鍵字可以定義一個輸入輸出形式參數(shù)眼俊。輸入輸出形式參數(shù)有一個能輸入給函數(shù)的值,函數(shù)能對其進(jìn)行修改粟关,還能輸出到函數(shù)外邊替換原來的值疮胖。輸入輸出形式參數(shù)不能有默認(rèn)值,可變形式參數(shù)不能標(biāo)記為 inout闷板,如果你給一個形式參數(shù)標(biāo)記了 inout澎灸,那么它們也不能標(biāo)記 var和 let了;
func swapTwoInts(_ a: inout Int, _ b: inout Int) {
? ? let temporaryA = a
? ? a = b
? ? b = temporaryA
}
39,reversedNames = names.sorted(by: { (s1: String, s2: String) -> Bool in return s1 > s2 } )
從語境中推斷類型:
因排序閉包為實際參數(shù)來傳遞給函數(shù),故 Swift 能推斷它的形式參數(shù)類型和返回類型遮晚。 sorted(by:) 方法期望它的第二個形式參數(shù)是一個 (String, String) -> Bool 類型的函數(shù)性昭。這意味著 (String, String)和 Bool 類型不需要被寫成閉包表達(dá)式定義中的一部分,因為所有的類型都能被推斷鹏漆,返回箭頭 ( ->) 和圍繞在形式參數(shù)名周圍的括號也能被省略:
reversedNames = names.sorted(by: { s1, s2 in return s1 > s2 } )
從單表達(dá)式閉包隱式返回:
單表達(dá)式閉包能夠通過從它們的聲明中刪掉 return 關(guān)鍵字來隱式返回它們單個表達(dá)式的結(jié)果巩梢,前面的栗子可以寫作:
reversedNames = names.sorted(by: { s1, s2 in s1 > s2 } )