Swift高手進階 - 11個技巧

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

1. 擴展(Extension)

任務: 求數字的平方。

// 菜鳥版func square(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 // 255.squared.squared // 625

2. 泛型(Generics)

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

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

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

// 高手版func printElementFromArray<T>(a: [T]) {        for element in a { 
            print(element) 
        } 
}

3. For 遍歷 vs While 遍歷

任務:打印 5 次 陸家嘴

// 菜鳥版var i = 0while 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?// 菜鳥版func userLogIn() {     if let username = myUsername {          if let password = myPassword {               print("優衣庫歡迎, \(username)"!)
          }
     }
}

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

// 高手版func userLogIn() {
     guard let username = myUsername, let password = myPassword 
          else { return } 
        print("優衣庫歡迎, \(username)!") 
}

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

5. 計算屬性 vs 函數

任務:計算圓的直徑

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

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

// 高手版var radius: Double = 10var diameter: Double {
      get { return radius * 2}      set { radius = newValue / 2} 
}
radius // 10diameter // 20diameter = 1000radius // 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 let Color = 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 函數

任務: 求兩個數字的和。

// 菜鳥版func sum(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.0func getDiameter(radius: Double) -> Double { 
      return radius * 2}

getDiameter(radius: radius) // return 20

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

// 高手版var diameter = 0var 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: Intinit(finger: Int, toe: Int) {  self.finger = finger  self.toe = toe }
}var daDi = Human(finger: 10, toe: 10)
daDi.finger // 10daDi.toe // 10

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

// 高手版class Human { var finger: Int
 var toe: Intinit(finger: Int, toe: Int) {  self.finger = finger  self.toe = toe
 }

  convenience init() {   self.init(finger: 10, toe: 10) // 調用主初始化方法
   } 
}var daDi = Human()
daDi.finger // 10daDi.toe // 10

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

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

十一條技巧講述完畢,打完收工。



文/豆志昂揚(簡書作者)

上一篇: 著名黑客發布基于網頁的盤古iOS 9.3.3越獄

下一篇: 來了 新的Visio和增強版Cortana將登陸 iOS

分享到: 更多
北京pk拾冠军杀号技巧 精准36码中特的网址 六复式5等于多少组 北京塞车开奖结果 逆袭欢乐生肖计划手机版 双色球走势图带坐标 足球计算器 七乐彩基本走势图 买彩票大小单双方法 重庆时时彩走势图 玩时时彩龙虎怎么稳赚 球探比分足球即时比分旧版 时时彩在线全天计划 500彩票计划软件北京PK拾 万人炸金花那里能下载 时时规律口诀