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的方式被調用的。

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

來源:簡書

上一篇: 昨夜2GB的更新包,iOS 10.2.1 B4都更新了些啥?

下一篇: iOS UIScrollView實現非全屏卡片效果

分享到: 更多
上海哪里可以玩老虎机 重庆时时采彩官方开奖 百人棋牌 四川麻将技巧 广东11选五计划软件苹果下载 澳门赌大小怎么玩 pk10长期稳赚9码 体彩十一选五投注表 11选5如何定胆 幸运飞艇一期五码计划稳定 定位胆8码倍投表 开个微信红包群猜大小单双 快三人工计划三期必中全开 彩票51计划app下载 后三组选包胆为什么只能买一个号 3分pk拾是真还是假的