程序遷移到swift 3.0的一些實(shí)用技巧
前言
在去年swift3.0發(fā)布了,新版本可以在Xcode 8中使用了,或者你可以直接從swift.org下載編譯器。
從代碼可讀性來(lái)看,新版本有很多提升,函數(shù)調(diào)用的連續(xù)性,更好的命名約定和移除了部分c風(fēng)格的元素。
從代碼可讀性來(lái)來(lái)看,NS前綴已經(jīng)從Foundation類(lèi)型中移除,例如NSBundle.mainBundle()
現(xiàn)在改為Bundle.mainBundle()
.
c風(fēng)格的一元操作符++和--在3.0中已經(jīng)不適用了:
// Only in Swift 2.2 and earlier var number = 10 number++ ++number number-- --number
相對(duì)應(yīng)的表達(dá)方式是number += 1 or number -= 1
.
另外一個(gè)有趣的變化是移除了c風(fēng)格的for-loop,我記得在學(xué)校中(使用c語(yǔ)言)寫(xiě)這種循環(huán):
// Only in Swift 2.2 and earlier let steps = 5 for var step = 0; step < steps; step++ { print(step) } // 0 1 2 3 4
主要的原因是存在了更好的對(duì)應(yīng)寫(xiě)循環(huán)的方法for-in
和stride().for-loop
在理解上比較困難和缺少swift風(fēng)格。當(dāng)新的方法出現(xiàn)后,for-loop
已經(jīng)很少在代碼庫(kù)中使用了。
這篇文章將講解典型的for-loop
使用場(chǎng)景,同時(shí)說(shuō)明遷移到 for-in
, stride()
或者簡(jiǎn)單的while() {}
.
一、如何遷移 for-loop 到 for-in
for-loop
應(yīng)用的典型場(chǎng)景在一個(gè)數(shù)字區(qū)間內(nèi)迭代。這些數(shù)字可以是數(shù)組的索引等.
例如,讓我們遍歷數(shù)組的每一個(gè)元素:
// Only in Swift 2.3 and earlier let birds = ["pigeon", "sparrow", "titmouse"] for var index = 0; index < birds.count; index++ { print(birds[index]) } // "pigeon" "sparrow" "titmouse"
可見(jiàn),let index = 0; index < birds.count; index++
的循環(huán)部分是冗長(zhǎng)的。許多元素是多余的,整個(gè)表達(dá)式可以簡(jiǎn)化的。替換為手動(dòng)的增量,整個(gè)操作可以用更具表達(dá)性的語(yǔ)法來(lái)自動(dòng)化。
for-in
循環(huán)更簡(jiǎn)短和更具表達(dá)性。讓我們遷移上面的代碼:
let birds = ['pigeon', 'sparrow', 'titmouse'] for index in 0..<birds.count { print(birds[index]) } // 'pigeon', 'sparrow', 'titmouse'
現(xiàn)在感覺(jué)好很多了。index in 0..<birds.count
更容易閱讀和理解。0..<birds.count
這部分定義一個(gè)半開(kāi)區(qū)間的 Range 類(lèi)型。for-in
循環(huán)迭代0,1和2的范圍值(不包括上限3)。
這不是全部! 你甚至可以跳過(guò)索引并直接訪問(wèn)數(shù)組元素:
let birds = ["pigeon", "sparrow", "titmouse"] for bird in birds { print(bird) } // "pigeon" "sparrow" "titmouse"
可以看出,對(duì)于標(biāo)準(zhǔn)數(shù)組或集合迭代for-in
對(duì)于for-loop
是一個(gè)更好的替代。 至少在這種情況下,在Swift 3.0中刪除for-lo
op的決定是合理的。
二、如何遷移 for-loop 到 stride
你可以合理地要求for-loop
雖然是冗長(zhǎng)的,但仍然是靈活的。 它對(duì)于更復(fù)雜的迭代是有用的。
讓我們嘗試一個(gè)場(chǎng)景。你要打印一個(gè)具有奇數(shù)索引元素的元素?cái)?shù)組。一個(gè) for-loop
可能看起來(lái)像這樣:
// Only in Swift 2.3 and earlier let colors = ["blue", "green", "red", "white", "black"] for var index = 0; index < colors.count; index += 2 { print(colors[index]) } // => "blue" "red" "black"
由于索引根據(jù)表達(dá)式 index += 2
而每次增加2,所以只有奇數(shù)索引的元素會(huì)被顯示:”blue”, “red” and “black”.
你可以嘗試使用 for-in
并定義一個(gè)范圍。但是需要奇數(shù)索引加上附加的驗(yàn)證:
let colors = ["blue", "green", "red", "white", "black"] for index in 0..<colors.count { if (index % 2 == 0) { print(colors[index]) } } // => "blue" "red" "black"
的確, if (index % 2 == 0) { ... }
條件句在這里看起來(lái)怎么樣。
這種情況很符合使用 Swift 的stride(from: value, to: value, by: value)
函數(shù)。定義開(kāi)始,結(jié)束(不包括上限)和步長(zhǎng)值,函數(shù)返回相應(yīng)的數(shù)字序列。
讓我們?cè)谖覀兊膱?chǎng)景中應(yīng)用stride:
let colors = ["blue", "green", "red", "white", "black"] for index in stride(from: 0, to: colors.count, by: 2) { print(colors[index]) } // => "blue" "red" "black"
stride(from: 0, to: colors.count, by: 2)
返回以0開(kāi)始到5的數(shù)字(上限不包含5),步長(zhǎng)為2。對(duì)于 for-loop
,這是一個(gè)好的替代。
如果上限必須包含進(jìn)來(lái),這里有另外一種函數(shù)格式:
stride(from: value, through: value, by: value)
。第二個(gè)參數(shù)的標(biāo)簽是 through, 這個(gè)標(biāo)簽是用以指明是包含上限的。
三、其他情況堅(jiān)持使用while
c風(fēng)格for-loop
的每個(gè)組件都有一個(gè)很好的屬性:初始化,跳出嚴(yán)重和完全可配置的增量:
for <initialization>; <verification>; <increment> { // loop body }
此外,你可以省略其中的任何組件,要是你能在for-loop
的循環(huán)塊打破循環(huán)。
例如,讓我們打印一個(gè)數(shù)字?jǐn)?shù)組的元素,直到數(shù)字0被遇到。可以使用C風(fēng)格的for-loop
:
// Only in Swift 2.2 and earlier let numbers = [1, 6, 2, 0, 7], nCount = numbers.count for var index = 0; index < nCount && numbers[index] != 0; index++ { print(numbers[index]) } // => 1 6 2
驗(yàn)證部分 index < nCount && numbers[index] != 0
是用以檢查是否0在數(shù)組中出現(xiàn)。如果出現(xiàn),則跳出循環(huán)。
所以只有0之前的數(shù)字被打印出來(lái):1,6和2。
for var index in 0..<nCount
是一個(gè)遷移選項(xiàng)。你只是需要使用條件 if numbers[index] == 0
,當(dāng)0出現(xiàn)的時(shí)候跳出循環(huán):
let numbers = [1, 6, 2, 0, 7], nCount = numbers.count for index in 0..<nCount { if (numbers[index] == 0) { break } print(numbers[index]) } // => 1 6 2
但 break 語(yǔ)句出現(xiàn),它會(huì)輕微減少閱讀流程。但是我想要容易地閱讀代碼流程!
while(<condition>) {...}
循環(huán)可能是一個(gè)更好的替代方案。讓我們看看上一個(gè)例子是如果被修改的:
let numbers = [1, 6, 2, 0, 7], nCount = numbers.count var index = 0 while (index < nCount && numbers[index] != 0) { print(numbers[index]) index += 1 } // => 1 6 2
如果你有的情況無(wú)法使用 for-in 或者 stride()
, 那么我推薦你使用 while(){}
。
四、統(tǒng)一參數(shù)標(biāo)簽行為
在Swift 2.2 和更早版本你可以在調(diào)用函數(shù)的時(shí)候忽略第一個(gè)參數(shù)的標(biāo)簽:
// Only in Swift 2.2 and earlier func sum(firstItem: Int, secondItem: Int) -> Int { return firstItem + secondItem } sum(5, secondItem: 2) // => 7
對(duì)于我來(lái)說(shuō),這個(gè)忽略的做法給我?guī)?lái)困擾。你不得不忽略第一個(gè)參數(shù)的標(biāo)簽,然而剩下的參數(shù)卻還保持有標(biāo)簽。這是一種不自然的規(guī)則。
幸運(yùn)的是從3.0版本開(kāi)始,所有參數(shù)將強(qiáng)制擁有標(biāo)簽。
讓我們來(lái)遷移上一個(gè)例子:
func sum(firstItem: Int, secondItem: Int) -> Int { return firstItem + secondItem } sum(firstItem: 5, secondItem: 2) // => 7
myFun(firstParam: 1, secondParam: 2)
看起來(lái)更好。你知道嚴(yán)格的參數(shù)含義。簡(jiǎn)單,一致和清晰的方式。
如果你因?yàn)槟承┰蛳朐赟wift 3.0中調(diào)用函數(shù)的時(shí)候忽略第一個(gè)標(biāo)簽,使用_ 作為那個(gè)參數(shù)的參數(shù)標(biāo)簽:
func sum(_ firstItem: Int, secondItem: Int) -> Int { return firstItem + secondItem } sum(5, secondItem: 2) // => 7
然而從長(zhǎng)遠(yuǎn)來(lái)看我不推薦這種做法。他破壞了Swift代碼中函數(shù)/方法調(diào)用的一致性。
Swift 命名向?qū)?有很多有用的命名方面的建議。
總結(jié)
Swift 3.0 做了一個(gè)很好的修改列表。其中大部分是重大的修改,所以你必須花些功夫來(lái)遷移Swift 2.3或者更舊的代碼。
Swift 的制造者花了很多功夫來(lái)使這門(mén)語(yǔ)言用起來(lái)盡可能的舒服。
有時(shí)候,這個(gè)過(guò)程產(chǎn)生重大更改。幸運(yùn)的是相比提高代碼的可讀性和跨語(yǔ)言語(yǔ)法的一致性來(lái)說(shuō),這是一個(gè)相對(duì)小的代價(jià)。
C風(fēng)格的元素如for-loop,一元增量和減量運(yùn)算被刪除。對(duì)于這些結(jié)構(gòu)Swift提供了更好的選擇。
例如C語(yǔ)言風(fēng)格的for循環(huán)很容易由for-in所取代。你可以使用stride()函數(shù)來(lái)進(jìn)行更多可配置的迭代。
我最喜歡的改進(jìn)是Swift 3.0引入了函數(shù)參數(shù)標(biāo)簽的一致性和清晰度。
簡(jiǎn)單易記的規(guī)則:始終指明參數(shù)的標(biāo)簽。
我建議你也訪問(wèn)Swift 3.0官方的遷移向?qū)А?/p>
英文原文鏈接:https://rainsoft.io/useful-tips-for-migrating-to-swift-3-0/
好了,以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者使用Swift能帶來(lái)一定的幫助,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
swift 3.0 實(shí)現(xiàn)短信驗(yàn)證碼倒計(jì)時(shí)功能
這篇文章主要介紹了swift 3.0 實(shí)現(xiàn)短信驗(yàn)證碼倒計(jì)時(shí)功能的相關(guān)資料,需要的朋友可以參考下2017-02-02swift4 使用DrawerController實(shí)現(xiàn)側(cè)滑菜單功能的示例代碼
這篇文章主要介紹了swift4 使用DrawerController實(shí)現(xiàn)側(cè)滑功能的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-06-06Spring中BeanFactory與FactoryBean的區(qū)別解讀
這篇文章主要介紹了Spring中BeanFactory與FactoryBean的區(qū)別解讀,Java的BeanFactory是Spring框架中的一個(gè)接口,它是用來(lái)管理和創(chuàng)建對(duì)象的工廠接口,在Spring中,我們可以定義多個(gè)BeanFactory來(lái)管理不同的組件,需要的朋友可以參考下2023-12-12Swift算法之二叉樹(shù)實(shí)現(xiàn)的方法示例
二叉樹(shù)是計(jì)算機(jī)科學(xué)中最基本也是最重要的樹(shù)型結(jié)構(gòu),最常見(jiàn)的二叉樹(shù)生成算法通常是使用遞歸或者其他描述類(lèi)語(yǔ)言的方法來(lái)實(shí)現(xiàn)。本文主要介紹了Swift算法之二叉樹(shù)實(shí)現(xiàn)的方法,文中介紹的非常詳細(xì),對(duì)大家具有一定的參考價(jià)值,需要的朋友們下面來(lái)一起看看吧。2017-03-03SwiftUI智能家居開(kāi)關(guān)燈頁(yè)面搭建示例
這篇文章主要為大家介紹了SwiftUI智能家居開(kāi)關(guān)燈頁(yè)面搭建示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08Swift開(kāi)發(fā)之使用UIRefreshControl實(shí)現(xiàn)下拉刷新數(shù)據(jù)及uirefreshcontrol使用
本文給大家介紹使用UIRefreshControl實(shí)現(xiàn)下拉刷新數(shù)據(jù),及UIRefreshControl的使用步驟,對(duì)本文感興趣的朋友一起學(xué)習(xí)吧2015-11-11