遷移到swift3.0有用的技巧

不久之前swift3.0發(fā)布了,新版本可以在Xcode 8中使用了,或者你可以直接從swift.org下載編譯器。

從代碼可讀性來看,新版本有很多提升,函數(shù)調(diào)用的連續(xù)性,更好的命名約定和移除了部分c風(fēng)格的元素。

從代碼可讀性來來看,NS前綴已經(jīng)從Foundation類型中移除,例如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語言)寫這種循環(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)寫循環(huán)的方法for-instride().for-loop在理解上比較困難和缺少swift風(fēng)格。當(dāng)新的方法出現(xiàn)后,for-loop已經(jīng)很少在代碼庫中使用了。

這篇文章將講解典型的for-loop使用場景,同時(shí)說明遷移到 for-in, stride()或者簡單的while() {}.

1. 如何遷移 for-loop 到 for-in

for-loop 應(yī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"

可見,let index = 0; index < birds.count; index++ 的循環(huán)部分是冗長的。許多元素是多余的,整個(gè)表達(dá)式可以簡化的。替換為手動(dòng)的增量,整個(gè)操作可以用更具表達(dá)性的語法來自動(dòng)化。

Image
Image

for-in 循環(huán)更簡短和更具表達(dá)性。讓我們遷移上面的代碼:

let birds = ['pigeon', 'sparrow', 'titmouse']  
for index in 0..<birds.count {  
  print(birds[index])
}
// 'pigeon', 'sparrow', 'titmouse'

現(xiàn)在感覺好很多了。index in 0..<birds.count 更容易閱讀和理解。0..<birds.count 這部分定義一個(gè)半開區(qū)間的 Range 類型。for-in 循環(huán)迭代0,1和2的范圍值(不包括上限3)。

這不是全部! 你甚至可以跳過索引并直接訪問數(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-loop的決定是合理的。

2. 如何遷移 for-loop 到 stride

你可以合理地要求for-loop雖然是冗長的,但仍然是靈活的。 它對(duì)于更復(fù)雜的迭代是有用的。

讓我們嘗試一個(gè)場景。你要打印一個(gè)具有奇數(shù)索引元素的元素?cái)?shù)組。一個(gè) for-loop 可能看起來像這樣:

// 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) { ... } 條件句在這里看起來怎么樣。

這種情況很符合使用 Swift 的stride(from: value, to: value, by: value)函數(shù)。定義開始,結(jié)束(不包括上限)和步長值,函數(shù)返回相應(yīng)的數(shù)字序列。

讓我們?cè)谖覀兊膱鼍爸袘?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開始到5的數(shù)字(上限不包含5),步長為2。對(duì)于 for-loop,這是一個(gè)好的替代。

如果上限必須包含進(jìn)來,這里有另外一種函數(shù)格式:
stride(from: value, through: value, by: value)。第二個(gè)參數(shù)的標(biāo)簽是 through, 這個(gè)標(biāo)簽是用以指明是包含上限的。

3. 其他情況堅(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ù)字被打印出來: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 語句出現(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

如果你有的情況無法使用 for-in 或者 stride(), 那么我推薦你使用 while(){}。

4. 統(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ì)于我來說,這個(gè)忽略的做法給我?guī)砝_。你不得不忽略第一個(gè)參數(shù)的標(biāo)簽,然而剩下的參數(shù)卻還保持有標(biāo)簽。這是一種不自然的規(guī)則。

Image
Image

幸運(yùn)的是從3.0版本開始,所有參數(shù)將強(qiáng)制擁有標(biāo)簽。
讓我們來遷移上一個(gè)例子:

func sum(firstItem: Int, secondItem: Int) -> Int {  
  return firstItem + secondItem
}
sum(firstItem: 5, secondItem: 2) // => 7  

myFun(firstParam: 1, secondParam: 2)看起來更好。你知道嚴(yán)格的參數(shù)含義。簡單,一致和清晰的方式。

如果你因?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 

然而從長遠(yuǎn)來看我不推薦這種做法。他破壞了Swift代碼中函數(shù)/方法調(diào)用的一致性。

Swift 命名向?qū)?有很多有用的命名方面的建議。

5. 總結(jié)

Swift 3.0 做了一個(gè)很好的修改列表。其中大部分是重大的修改,所以你必須花些功夫來遷移Swift 2.3或者更舊的代碼。

Swift 的制造者花了很多功夫來使這門語言用起來盡可能的舒服。
有時(shí)候,這個(gè)過程產(chǎn)生重大更改。幸運(yùn)的是相比提高代碼的可讀性和跨語言語法的一致性來說,這是一個(gè)相對(duì)小的代價(jià)。

C風(fēng)格的元素如for-loop,一元增量和減量運(yùn)算被刪除。對(duì)于這些結(jié)構(gòu)Swift提供了更好的選擇。
例如C語言風(fēng)格的for循環(huán)很容易由for-in所取代。你可以使用stride()函數(shù)來進(jìn)行更多可配置的迭代。

我最喜歡的改進(jìn)是Swift 3.0引入了函數(shù)參數(shù)標(biāo)簽的一致性和清晰度。簡單易記的規(guī)則:始終指明參數(shù)的標(biāo)簽。

我建議你也訪問Swift 3.0官方的遷移向?qū)А?/p>

英文原文鏈接:https://rainsoft.io/useful-tips-for-migrating-to-swift-3-0/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容