Swift高手進階 – 10個技巧

CatherineBa 8年前發布 | 5K 次閱讀 Swift Apple Swift開發

Swift秘籍

聽說你已經學習Swift幾個月了,有沒有想更進一步成為Swift高手的想法?我這里有11招秘技,各位施主且聽我慢慢道來,結個善緣。

1. 擴展(Extension)

任務: 求數字的平方。

// 菜鳥版
funcsquare(x: Int) -> Int { return x * x }
var squaredOfFive = square(x: 5)
square(x: squaredOfFive) // 625

為了求5的四次方我們被迫創建變量 squaredOfFive — 高手可不喜歡被迫定義一個無用的變量。

// 高手版
extension Int { 
 var squared: Int { return self * self }
}
5.squared // 25
5.squared.squared // 625

2. 泛型(Generics)

任務:打印輸出數組內所有的元素。

// 菜鳥版
var stringArray = ["蒼老師", "范老師", "優衣庫"]
var intArray = [1, 3, 4, 5, 6]
var doubleArray = [1.0, 2.0, 3.0]
funcprintStringArray(a: [String]) { 
        for s in a { 
              print(s) 
        }
}
funcprintIntArray(a: [Int]) { for i in a { print(i) } }
funcprintDoubleArray(a: [Double]) {for d in a { print(d) } }

居然要定義這么多函數? 菜鳥能忍高手不能忍!!!

// 高手版
funcprintElementFromArray(a: [T]) {
        for element in a { 
            print(element) 
        } 
}

3. For 遍歷 vs While 遍歷

任務:打印 5 次 陸家嘴

// 菜鳥版
var i = 0
while 5 > i {
      print("陸家嘴")
      i += 1 
}

被迫定義了變量 i 來確保打印 陸家嘴 5 次。

注意定義越多的變量,越多的潛在風險,越多的生活問題。這就是蝴蝶效應,你難道想X生活不和諧?

// 高手版
for _ in 1...5 { 
    print("陸家嘴") 
}

上面的代碼實在是簡潔,美妙。

4. Gaurd let vs if let

任務 : 讓我們寫個歡迎新用戶的程序。

var myUsername: Double?
var myPassword: Double?
// 菜鳥版
funcuserLogIn() {
    if letusername = myUsername {
          if letpassword = myPassword {
              print("優衣庫歡迎, \(username)"!)
          }
    }
}

這些令人討厭的嵌套代碼,我們要消滅它

// 高手版
funcuserLogIn() {
    guardletusername = myUsername, letpassword = myPassword 
          else { return } 
        print("優衣庫歡迎, \(username)!") 
}

注意這里如果myUsername 或 myPassword nil,都會提前結束,否則就會打印 “優衣庫歡迎, XXX”

5. 計算屬性 vs 函數

任務:計算圓的直徑

// 菜鳥版
funcgetDiameter(radius: Double) -> Double { return radius * 2}
funcgetRadius(diameter: Double) -> Double { return diameter / 2}
getDiameter(radius: 10) // return 20
getRadius(diameter: 200) // return 100
getRadius(diameter: 600) // return 300

上面我們創建了2個毫無關系的函數,可是直徑和周長兩者真的沒有關系嗎?

// 高手版
var radius: Double = 10
var diameter: Double {
      get { return radius * 2}
      set { radius = newValue / 2} 
}
radius // 10
diameter // 20
diameter = 1000
radius // 500

現在半徑和直徑相互依賴,真實地反應了兩者的關系。

記得上面說的蝴蝶效應嗎? 越少的依賴,代碼越簡潔,問題越少,生活越美好!

6. 枚舉 – 類型安全

任務:賣門票

// 菜鳥版
switch "Adult" {
  case "Adult": print("請付 50 元")
  case "Child": print("請付 25 元")
  case "Senior": print("請付 30 元")
  default: print("你確認不是僵尸嗎,哥們?") 
}

“Adult”, “Child”, “Senior” 這里都是硬編碼,你每次需要輸入手動輸入這些字符,記得我們上面講到的嗎? 手動鍵入越少,錯誤越少,生活越美好。

// 高手版
enum People { case adult, child, senior }
switch People.adult {
  case .adult: print("請付 50 元")
  case .child: print("請付 25 元")
  case .senior: print("請付 30 元")
  default: print("你確認不是僵尸嗎,哥們?") 
}

這樣你就避免了不小心輸入錯誤的問題,因為 “.adult”, “.child”, “.senior” 被定義成了enum’, 任何不在預定義范圍內的實例都會被Xcode毫不留情的指出來,合理利用集成開發環境是高手必備的。

7. 空合運算符

任務: 用戶選擇微博主體顏色。

// 菜鳥版
var userChosenColor: String? 
var defaultColor = "Red"
var colorToUse = ""
if letColor = userChosenColor { 
    colorToUse = Color 
} else { 
    colorToUse = defaultColor
 }

這也太臃腫了吧,讓我們來減減肥。

// 高手版
var colorToUse = userChosenColor ?? defaultColor

稍微解釋一下, 如 userChosenColor 為 nil, 則選擇 defaultColor, 否則則userChosenColor.

其實空合運算符是對以下代碼的簡短表達方法。

a != nil ? a! : b

8. 函數式編程

任務: 獲取偶數。

// 菜鳥版
var newEvens = [Int]()
for i in 1...10 {
  if i % 2 == 0 { 
      newEvens.append(i) 
    } 
}
print(newEvens) // [2, 4, 6, 8, 10]

這種for循環真是冗長,讓人看的昏昏欲睡。

// 高手版
var evens = (1...10).filter { $0 % 2 == 0 } 
print(evens) 
// [2, 4, 6, 8, 10]

有沒有感覺函數式編程讓你看起來聰明多了。

9. 閉包 vs 函數

任務: 求兩個數字的和。

// 菜鳥版
funcsum(x: Int, y: Int) -> Int { 
    return x + y 
}
var result = sum(x: 5, y: 6) // 11

為了這個功能我還需要記住函數名 和 變量名? 能不能少一個呢?

// 高手版
var sumUsingClosure: (Int, Int) -> (Int) = { $0 + $1 }
sumUsingClosure(5, 6) // 11

10. 屬性觀測器

任務:計算圓的直徑

// 菜鳥版
var radius = 10.0
funcgetDiameter(radius: Double) -> Double { 
      return radius * 2
}
 
getDiameter(radius: radius) // return 20

這里是不需要專門定義函數的。

// 高手版
var diameter = 0
var radius: Double = 10 {
      willSet { print("準備賦值中") }
      didSet { diameter =radius * 2}
    }
}
radius  = 10 // 準備賦值中
diameter // 20.0

willSet會在給變量radius賦值前調用,而 didSet 會在給變量radius賦值后調用。

11.便利初始化

任務: 一個人有多少根手指和腳趾

// 菜鳥版
class Human {
 var finger: Int
 var toe: Int
 
init(finger: Int, toe: Int) {
  self.finger = finger
  self.toe = toe }
}
 
 
var daDi = Human(finger: 10, toe: 10)
daDi.finger // 10
daDi.toe // 10

因為絕大部分人都有十根手指和腳趾,可以初始化時預先賦值。

// 高手版
class Human {
 var finger: Int
 var toe: Int
 
init(finger: Int, toe: Int) {
  self.finger = finger
  self.toe = toe
 }
 
  convenienceinit() {
  self.init(finger: 10, toe: 10) // 調用主初始化方法
  } 
}
 
var daDi = Human()
daDi.finger // 10
daDi.toe // 10

Swift中可以在init初始化方法前加上convenience關鍵字,這類方法主要提供使用上的方便。

所有的convenience初始化方法都必須調用同一個類中的頂級初始化方法完成初始化。另外convenience的初始化方法是不能被子類重寫或從子類中以super的方式被調用的。

 

 

來自:http://ios.jobbole.com/91503/

 

 本文由用戶 CatherineBa 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!