听说你已经学习Swift几个月了,有没有想更进一步成为Swift高手的想法?我这里有11招秘技,各位施主且听我慢慢道来,结个善缘。

1. 扩展(Extension)

任务: 求数字的平方。

  1. // 菜鸟版
  2. func square(x: Int) -> Int { return x * x }
  3. var squaredOfFive = square(x: 5)
  4. square(x: squaredOfFive) // 625

为了求5的四次方我们被迫创建变量 squaredOfFive — 高手可不喜欢被迫定义一个无用的变量。

  1. // 高手版
  2. extension Int {
  3. var squared: Int { return self * self }
  4. }
  5. 5.squared // 25
  6. 5.squared.squared // 625

2. 泛型(Generics)

任务:打印输出数组内所有的元素。

  1. // 菜鸟版
  2. var stringArray = ["金庸", "古龙", "梁羽生"]
  3. var intArray = [1, 3, 4, 5, 6]
  4. var doubleArray = [1.0, 2.0, 3.0]
  5. func printStringArray(a: [String]) {
  6. for s in a {
  7. print(s)
  8. }
  9. }
  10. func printIntArray(a: [Int]) { for i in a { print(i) } }
  11. func printDoubleArray(a: [Double]) {for d in a { print(d) } }

居然要定义这么多函数? 菜鸟能忍高手不能忍!!!

  1. // 高手版
  2. func printElementFromArray<T>(a: [T]) {
  3. for element in a {
  4. print(element)
  5. }
  6. }

3. For 遍历 vs While 遍历

任务:打印 5 次 陆家嘴

  1. // 菜鸟版
  2. var i = 0
  3. while 5 > i {
  4. print("陆家嘴")
  5. i += 1
  6. }

被迫定义了变量 i 来确保打印 陆家嘴 5 次。
注意定义越多的变量,越多的潜在风险,越多的生活问题。这就是蝴蝶效应,你难道想X生活不和谐?

  1. // 高手版
  2. for _ in 1...5 {
  3. print("陆家嘴")
  4. }

上面的代码实在是简洁,美妙。

4. Gaurd let vs if let

任务 : 让我们写个欢迎新用户的程序。

  1. var myUsername: Double?
  2. var myPassword: Double?
  3. // 菜鸟版
  4. func userLogIn() {
  5. if let username = myUsername {
  6. if let password = myPassword {
  7. print("华山派欢迎, \(username)"!)
  8. }
  9. }
  10. }

这些令人讨厌的嵌套代码,我们要消灭它

  1. // 高手版
  2. func userLogIn() {
  3. guard let username = myUsername, let password = myPassword
  4. else { return }
  5. print("华山派欢迎, \(username)!")
  6. }

注意这里如果myUsername 或 myPassword nil,都会提前结束,否则就会打印 “优衣库欢迎, XXX”

5. 计算属性 vs 函数

任务:计算圆的直径

  1. // 菜鸟版
  2. func getDiameter(radius: Double) -> Double { return radius * 2}
  3. func getRadius(diameter: Double) -> Double { return diameter / 2}
  4. getDiameter(radius: 10) // return 20
  5. getRadius(diameter: 200) // return 100
  6. getRadius(diameter: 600) // return 300

上面我们创建了2个毫无关系的函数,可是直径和周长两者真的没有关系吗?

  1. // 高手版
  2. var radius: Double = 10
  3. var diameter: Double {
  4. get { return radius * 2}
  5. set { radius = newValue / 2}
  6. }
  7. radius // 10
  8. diameter // 20
  9. diameter = 1000
  10. radius // 500

现在半径和直径相互依赖,真实地反应了两者的关系。
记得上面说的蝴蝶效应吗? 越少的依赖,代码越简洁,问题越少,生活越美好!

6. 枚举 - 类型安全

任务:卖门票

  1. // 菜鸟版
  2. switch "Adult" {
  3. case "Adult": print("请付 50 元")
  4. case "Child": print("请付 25 元")
  5. case "Senior": print("请付 30 元")
  6. default: print("你确认不是僵尸吗,哥们?")
  7. }

“Adult”, “Child”, “Senior” 这里都是硬编码,你每次需要输入手动输入这些字符,记得我们上面讲到的吗? 手动键入越少,错误越少,生活越美好。

  1. // 高手版
  2. enum People { case adult, child, senior }
  3. switch People.adult {
  4. case .adult: print("请付 50 元")
  5. case .child: print("请付 25 元")
  6. case .senior: print("请付 30 元")
  7. default: print("你确认不是僵尸吗,哥们?")
  8. }

这样你就避免了不小心输入错误的问题,因为 “.adult”, “.child”, “.senior” 被定义成了enum', 任何不在预定义范围内的实例都会被Xcode毫不留情的指出来,合理利用集成开发环境是高手必备的。

7. 空合运算符

任务: 用户选择微博主体颜色。

  1. // 菜鸟版
  2. var userChosenColor: String?
  3. var defaultColor = "Red"
  4. var colorToUse = ""
  5. if let Color = userChosenColor {
  6. colorToUse = Color
  7. } else {
  8. colorToUse = defaultColor
  9. }

这也太臃肿了吧,让我们来减减肥。

  1. // 高手版
  2. var colorToUse = userChosenColor ?? defaultColor

稍微解释一下, 如 userChosenColor 为 nil, 则选择 defaultColor, 否则则userChosenColor.
其实空合运算符是对以下代码的简短表达方法。

  1. a != nil ? a! : b

8. 函数式编程

任务: 获取偶数。

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

这种for循环真是冗长,让人看的昏昏欲睡。

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

有没有感觉函数式编程让你看起来聪明多了。

9. 闭包 vs 函数

任务: 求两个数字的和。

  1. // 菜鸟版
  2. func sum(x: Int, y: Int) -> Int {
  3. return x + y
  4. }
  5. var result = sum(x: 5, y: 6) // 11

为了这个功能我还需要记住函数名 和 变量名? 能不能少一个呢?

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

10. 属性观测器

任务:计算圆的直径

  1. // 菜鸟版
  2. var radius = 10.0
  3. func getDiameter(radius: Double) -> Double {
  4. return radius * 2
  5. }
  6. getDiameter(radius: radius) // return 20

这里是不需要专门定义函数的。

  1. // 高手版
  2. var diameter = 0
  3. var radius: Double = 10 {
  4. willSet { print("准备赋值中") }
  5. didSet { diameter =radius * 2}
  6. }
  7. }
  8. radius = 10 // 准备赋值中
  9. diameter // 20.0

willSet 会在给变量radius赋值前调用,而 didSet 会在给变量radius赋值后调用。

11.便利初始化

任务: 一个人有多少根手指和脚趾

  1. // 菜鸟版
  2. class Human {
  3. var finger: Int
  4. var toe: Int
  5. init(finger: Int, toe: Int) {
  6. self.finger = finger
  7. self.toe = toe }
  8. }
  9. var daDi = Human(finger: 10, toe: 10)
  10. daDi.finger // 10
  11. daDi.toe // 10

因为绝大部分人都有十根手指和脚趾,可以初始化时预先赋值。

  1. // 高手版
  2. class Human {
  3. var finger: Int
  4. var toe: Int
  5. init(finger: Int, toe: Int) {
  6. self.finger = finger
  7. self.toe = toe
  8. }
  9. convenience init() {
  10. self.init(finger: 10, toe: 10) // 调用主初始化方法
  11. }
  12. }
  13. var daDi = Human()
  14. daDi.finger // 10
  15. daDi.toe // 10

Swift中可以在init初始化方法前加上convenience关键字,这类方法主要提供使用上的方便。

所有的convenience初始化方法都必须调用同一个类中的顶级初始化方法完成初始化。另外convenience的初始化方法是不能被子类重写或从子类中以super的方式被调用的。

12. 延迟初始化

任务: 定义一个包含pi常量作为属性的类。

  1. // 菜鸟版
  2. class MathHelper {
  3. var pi: Double = {
  4. // 计算pi
  5. return resultOfCalculation
  6. }()
  7. }

计算pi的工作量是繁重的,且对于调用者不是必须的,可以假想下MathHelper内包含数十个类pi常量的场景,如果不在使用的时候再初始化常量会浪费多少宝贵的计算资源。

  1. // 高手版
  2. class MathHelper {
  3. lazy var pi: Double = {
  4. // 计算pi
  5. return resultOfCalculation
  6. }()
  7. }

lazy 一方面可以让初始化成本较高的变量延迟初始化,提高资源利用效率。另一方面可以延迟初始化具有外部依赖的属性变量。

  1. class Person {
  2. var name: String
  3. lazy var personalizedGreeting: String = {
  4. [unowned self] in
  5. return "Hello, \(self.name)!"
  6. }()
  7. init(name: String) {
  8. self.name = name
  9. }
  10. }

上面的例子中,属性personalizedGreeting依赖于变量name。

十二条技巧讲述完毕,打完收工。

作者:豆志昂扬
链接:https://www.jianshu.com/p/eabaaae88533
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

Swift进阶 - 12个技巧的更多相关文章

  1. Swift 进阶

    iOS开发系列--Swift进阶 2015-09-21 00:01 by KenshinCui, 3072 阅读, 12 评论, 收藏, 编辑 概述 上一篇文章<iOS开发系列--Swift语言 ...

  2. Sublime Text编辑器的12个技巧和诀窍

    本文为您提供Sublime Text编辑器的12个技巧和诀窍,深入挖掘这个看似简洁的代码编辑器,背后所隐藏的实现各种高级功能的无限可能. 1) 选择 以下是一些Sublime Text选择文本的快捷键 ...

  3. [.net 面向对象程序设计进阶] (12) 序列化(Serialization)(四) 快速掌握JSON的序列化和反序列化

    [.net 面向对象程序设计进阶] (12) 序列化(Serialization)(四) 快速掌握JSON的序列化和反序列化 本节导读: 介绍JSON的结构,在JS中的使用.重点说明JSON如何在.N ...

  4. PowerDesigner 12小技巧-pd小技巧-pd工具栏不见了-pd修改外键命名规则-pd添加外键

    PowerDesigner 12小技巧-pd小技巧-pd工具栏不见了-pd修改外键命名规则-pd添加外键 1. 附加:工具栏不见了 调色板(Palette)快捷工具栏不见了PowerDesigner ...

  5. python进阶12 Redis

    python进阶12 Redis 一.概念 #redis是一种nosql(not only sql)数据库,他的数据是保存在内存中,同时redis可以定时把内存数据同步到磁盘,即可以将数据持久化,还提 ...

  6. js进阶 12 jquery事件汇总

    js进阶 12 jquery事件汇总 一.常用事件 页面载入事件 ready() 文档就绪事件(当 HTML 文档就绪可用时) 鼠标事件 click() 触发.或将函数绑定到指定元素的 click 事 ...

  7. CSS进阶内容——布局技巧和细节修饰

    CSS进阶内容--布局技巧和细节修饰 我们在之前的文章中已经掌握了CSS的大部分内容,但仍有一些内容我们没有涉略,这篇文章就是为了补充前面没有涉及的内容,为我们的知识做出补充并且介绍一些布局技巧 当然 ...

  8. MVC进阶讲解+小技巧-乱七八糟

    开发步骤 1.建立项目 2.建立文件夹 3.建立Controllers 4.生成页面 5.编写Html+Js 6.编写异步请求的Action的方法,返回部分页(用于分页) 7.Js中显示部分页 8.增 ...

  9. IOS开发之SWIFT进阶部分

    概述 上一篇文章<iOS开发系列--Swift语言> 中对Swift的语法特点以及它和C.ObjC等其他语言的用法区别进行了介绍.当然,这只是Swift的入门基础,但是仅仅了解这些对于使用 ...

随机推荐

  1. C/C++知识要点4——printf函数以及cout的计算顺序

    printf函数的计算顺序:先从右到左压栈,然后从左到右出栈. 例程: #include"stdio.h" int main() { int arr[] = { 1, 2, 3, ...

  2. openWRT自学---基于backfire版本,分析其Make命令的执行过程和各阶段的主要产物

    准备阶段:从SVN下载backfire的编译环境(位置是:svn co svn://svn.openwrt.org/openwrt/branches/backfire),然后按照openWRT的要求, ...

  3. Ecshop提示Only variables should be passed by reference in错误

    Ecshop是个坑爹货,为什么tiandi会说它是个坑爹货呢,请看一下下面的官方的运行环境推荐: 服务器端运行环境推荐·php版本5.0以上5.3以下的版本(推荐使用5.2系列版本)·Mysql版本5 ...

  4. 我的第五个程序 java的JDBC连接mysql数据库 实现输入查询

    import java.sql.*; import java.util.Scanner; public class JDBCTest { public static void main(String[ ...

  5. 第一百九十一节,jQuery EasyUI 入门

    jQuery EasyUI 入门 学习要点: 1.什么是 jQuery EasyUI 2.学习 jQuery EasyUI 的条件 3.jQuery EasyUI 的功能和优势 4.其他的 UI 插件 ...

  6. Hibernate每个具体类一张表映射(使用XML)

    在每个具体类一个表中,数据库中将有三个表但彼此之间没有关系(关联). 根据具体类策略将表格映射到表有两种方法. 由union-subclass元素指定 通过自我为每个类创建表 我们来了解映射的层次结构 ...

  7. sqoop-1.4.4安装配置

    环境:redhat6.5 hadoop2.4.1 感谢: http://wenku.baidu.com/view/a9083da8dd3383c4bb4cd274.html注释hbase检查 感谢: ...

  8. 深入了解UIAutomation 的API

    有关UiAUiAutomation的API对象的文件名称. 1.UIAutomation中的对象都是以UIA#####开头的出现的.eg:UIAButton 2.有关Logger对象负责日志的输出 U ...

  9. jquery遍历json与数组方法总结

    来自:http://www.php100.com/html/program/jquery/2013/0905/5927.html 先我们来参考each() 方法,each()规定为每个匹配元素规定运行 ...

  10. shell中${}的使用

    1. 截断功能${file#*/}:       拿掉第一条/及其左边的字符串:dir1/dir2/dir3/my.file.txt${file##*/}:    拿掉最后一条/及其左边的字符串:my ...