Swift高手进阶 – 10个技巧

CatherineBa 7年前
   <p style="text-align: center;"><img src="https://simg.open-open.com/show/157be3b938846c2f8f562282e4524855.jpg"></p>    <p style="text-align:center">Swift秘籍</p>    <p>听说你已经学习Swift几个月了,有没有想更进一步成为Swift高手的想法?我这里有11招秘技,各位施主且听我慢慢道来,结个善缘。</p>    <p><strong>1. 扩展(Extension)</strong></p>    <p>任务: 求数字的平方。</p>    <pre>  <code class="language-swift">// 菜鸟版  funcsquare(x: Int) -> Int { return x * x }  var squaredOfFive = square(x: 5)  square(x: squaredOfFive) // 625  </code></pre>    <p>为了求5的四次方我们被迫创建变量 squaredOfFive — 高手可不喜欢被迫定义一个无用的变量。</p>    <pre>  <code class="language-swift">// 高手版  extension Int {    var squared: Int { return self * self }  }  5.squared // 25  5.squared.squared // 625  </code></pre>    <p><strong>2. 泛型(Generics)</strong></p>    <p>任务:打印输出数组内所有的元素。</p>    <pre>  <code class="language-swift">// 菜鸟版  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) } }  </code></pre>    <p>居然要定义这么多函数? 菜鸟能忍高手不能忍!!!</p>    <pre>  <code class="language-swift">// 高手版  funcprintElementFromArray(a: [T]) {          for element in a {               print(element)           }   }  </code></pre>    <p><strong>3. For 遍历 vs While 遍历</strong></p>    <p>任务:打印 5 次 陆家嘴</p>    <pre>  <code class="language-swift">// 菜鸟版  var i = 0  while 5 > i {        print("陆家嘴")        i += 1   }  </code></pre>    <p>被迫定义了变量 i 来确保打印 陆家嘴 5 次。</p>    <p>注意定义越多的变量,越多的潜在风险,越多的生活问题。这就是蝴蝶效应,你难道想X生活不和谐?</p>    <pre>  <code class="language-swift">// 高手版  for _ in 1...5 {       print("陆家嘴")   }  </code></pre>    <p>上面的代码实在是简洁,美妙。</p>    <p><strong>4. Gaurd let vs if let</strong></p>    <p>任务 : 让我们写个欢迎新用户的程序。</p>    <pre>  <code class="language-swift">var myUsername: Double?  var myPassword: Double?  // 菜鸟版  funcuserLogIn() {      if letusername = myUsername {            if letpassword = myPassword {                print("优衣库欢迎, \(username)"!)            }      }  }  </code></pre>    <p>这些令人讨厌的嵌套代码,我们要消灭它</p>    <pre>  <code class="language-swift">// 高手版  funcuserLogIn() {      guardletusername = myUsername, letpassword = myPassword             else { return }           print("优衣库欢迎, \(username)!")   }  </code></pre>    <p>注意这里如果myUsername 或 myPassword nil,都会提前结束,否则就会打印 “优衣库欢迎, XXX”</p>    <p><strong>5. 计算属性 vs 函数</strong></p>    <p>任务:计算圆的直径</p>    <pre>  <code class="language-swift">// 菜鸟版  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  </code></pre>    <p>上面我们创建了2个毫无关系的函数,可是直径和周长两者真的没有关系吗?</p>    <pre>  <code class="language-swift">// 高手版  var radius: Double = 10  var diameter: Double {        get { return radius * 2}        set { radius = newValue / 2}   }  radius // 10  diameter // 20  diameter = 1000  radius // 500  </code></pre>    <p>现在半径和直径相互依赖,真实地反应了两者的关系。</p>    <p>记得上面说的蝴蝶效应吗? 越少的依赖,代码越简洁,问题越少,生活越美好!</p>    <p><strong>6. 枚举 – 类型安全</strong></p>    <p>任务:卖门票</p>    <pre>  <code class="language-swift">// 菜鸟版  switch "Adult" {    case "Adult": print("请付 50 元")    case "Child": print("请付 25 元")    case "Senior": print("请付 30 元")    default: print("你确认不是僵尸吗,哥们?")   }  </code></pre>    <p>“Adult”, “Child”, “Senior” 这里都是硬编码,你每次需要输入手动输入这些字符,记得我们上面讲到的吗? 手动键入越少,错误越少,生活越美好。</p>    <pre>  <code class="language-swift">// 高手版  enum People { case adult, child, senior }  switch People.adult {    case .adult: print("请付 50 元")    case .child: print("请付 25 元")    case .senior: print("请付 30 元")    default: print("你确认不是僵尸吗,哥们?")   }  </code></pre>    <p>这样你就避免了不小心输入错误的问题,因为 “.adult”, “.child”, “.senior” 被定义成了enum’, 任何不在预定义范围内的实例都会被Xcode毫不留情的指出来,合理利用集成开发环境是高手必备的。</p>    <p><strong>7. 空合运算符</strong></p>    <p>任务: 用户选择微博主体颜色。</p>    <pre>  <code class="language-swift">// 菜鸟版  var userChosenColor: String?   var defaultColor = "Red"  var colorToUse = ""  if letColor = userChosenColor {       colorToUse = Color   } else {       colorToUse = defaultColor   }  </code></pre>    <p>这也太臃肿了吧,让我们来减减肥。</p>    <pre>  <code class="language-swift">// 高手版  var colorToUse = userChosenColor ?? defaultColor  </code></pre>    <p>稍微解释一下, 如 userChosenColor 为 nil, 则选择 defaultColor, 否则则userChosenColor.</p>    <p>其实空合运算符是对以下代码的简短表达方法。</p>    <pre>  <code class="language-swift">a != nil ? a! : b  </code></pre>    <p><strong>8. 函数式编程</strong></p>    <p>任务: 获取偶数。</p>    <pre>  <code class="language-swift">// 菜鸟版  var newEvens = [Int]()  for i in 1...10 {    if i % 2 == 0 {         newEvens.append(i)       }   }  print(newEvens) // [2, 4, 6, 8, 10]  </code></pre>    <p>这种for循环真是冗长,让人看的昏昏欲睡。</p>    <pre>  <code class="language-swift">// 高手版  var evens = (1...10).filter { $0 % 2 == 0 }   print(evens)   // [2, 4, 6, 8, 10]  </code></pre>    <p>有没有感觉函数式编程让你看起来聪明多了。</p>    <p><strong>9. 闭包 vs 函数</strong></p>    <p>任务: 求两个数字的和。</p>    <pre>  <code class="language-swift">// 菜鸟版  funcsum(x: Int, y: Int) -> Int {       return x + y   }  var result = sum(x: 5, y: 6) // 11  </code></pre>    <p>为了这个功能我还需要记住函数名 和 变量名? 能不能少一个呢?</p>    <pre>  <code class="language-swift">// 高手版  var sumUsingClosure: (Int, Int) -> (Int) = { $0 + $1 }  sumUsingClosure(5, 6) // 11  </code></pre>    <p><strong>10. 属性观测器</strong></p>    <p>任务:计算圆的直径</p>    <pre>  <code class="language-swift">// 菜鸟版  var radius = 10.0  funcgetDiameter(radius: Double) -> Double {         return radius * 2  }     getDiameter(radius: radius) // return 20  </code></pre>    <p>这里是不需要专门定义函数的。</p>    <pre>  <code class="language-swift">// 高手版  var diameter = 0  var radius: Double = 10 {        willSet { print("准备赋值中") }        didSet { diameter =radius * 2}      }  }  radius  = 10 // 准备赋值中  diameter // 20.0  </code></pre>    <p>willSet会在给变量radius赋值前调用,而 <strong>didSet</strong> 会在给变量radius赋值后调用。</p>    <p><strong>11.便利初始化</strong></p>    <p>任务: 一个人有多少根手指和脚趾</p>    <pre>  <code class="language-swift">// 菜鸟版  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  </code></pre>    <p>因为绝大部分人都有十根手指和脚趾,可以初始化时预先赋值。</p>    <pre>  <code class="language-swift">// 高手版  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  </code></pre>    <p>Swift中可以在init初始化方法前加上convenience关键字,这类方法主要提供使用上的方便。</p>    <p>所有的convenience初始化方法都必须调用同一个类中的顶级初始化方法完成初始化。另外convenience的初始化方法是不能被子类重写或从子类中以super的方式被调用的。</p>    <p> </p>    <p> </p>    <p>来自:http://ios.jobbole.com/91503/</p>    <p> </p>