Swift进阶 - 12个技巧
听说你已经学习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 // 25
5.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 = 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?
// 菜鸟版
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 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 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.0
func getDiameter(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
}
convenience init() {
self.init(finger: 10, toe: 10) // 调用主初始化方法
}
}
var daDi = Human()
daDi.finger // 10
daDi.toe // 10
Swift中可以在init初始化方法前加上convenience关键字,这类方法主要提供使用上的方便。
所有的convenience初始化方法都必须调用同一个类中的顶级初始化方法完成初始化。另外convenience的初始化方法是不能被子类重写或从子类中以super的方式被调用的。
12. 延迟初始化
任务: 定义一个包含pi常量作为属性的类。
// 菜鸟版
class MathHelper {
var pi: Double = {
// 计算pi
return resultOfCalculation
}()
}
计算pi的工作量是繁重的,且对于调用者不是必须的,可以假想下MathHelper内包含数十个类pi常量的场景,如果不在使用的时候再初始化常量会浪费多少宝贵的计算资源。
// 高手版
class MathHelper {
lazy var pi: Double = {
// 计算pi
return resultOfCalculation
}()
}
lazy 一方面可以让初始化成本较高的变量延迟初始化,提高资源利用效率。另一方面可以延迟初始化具有外部依赖的属性变量。
class Person {
var name: String
lazy var personalizedGreeting: String = {
[unowned self] in
return "Hello, \(self.name)!"
}()
init(name: String) {
self.name = name
}
}
上面的例子中,属性personalizedGreeting依赖于变量name。
十二条技巧讲述完毕,打完收工。
作者:豆志昂扬
链接:https://www.jianshu.com/p/eabaaae88533
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Swift进阶 - 12个技巧的更多相关文章
- Swift 进阶
iOS开发系列--Swift进阶 2015-09-21 00:01 by KenshinCui, 3072 阅读, 12 评论, 收藏, 编辑 概述 上一篇文章<iOS开发系列--Swift语言 ...
- Sublime Text编辑器的12个技巧和诀窍
本文为您提供Sublime Text编辑器的12个技巧和诀窍,深入挖掘这个看似简洁的代码编辑器,背后所隐藏的实现各种高级功能的无限可能. 1) 选择 以下是一些Sublime Text选择文本的快捷键 ...
- [.net 面向对象程序设计进阶] (12) 序列化(Serialization)(四) 快速掌握JSON的序列化和反序列化
[.net 面向对象程序设计进阶] (12) 序列化(Serialization)(四) 快速掌握JSON的序列化和反序列化 本节导读: 介绍JSON的结构,在JS中的使用.重点说明JSON如何在.N ...
- PowerDesigner 12小技巧-pd小技巧-pd工具栏不见了-pd修改外键命名规则-pd添加外键
PowerDesigner 12小技巧-pd小技巧-pd工具栏不见了-pd修改外键命名规则-pd添加外键 1. 附加:工具栏不见了 调色板(Palette)快捷工具栏不见了PowerDesigner ...
- python进阶12 Redis
python进阶12 Redis 一.概念 #redis是一种nosql(not only sql)数据库,他的数据是保存在内存中,同时redis可以定时把内存数据同步到磁盘,即可以将数据持久化,还提 ...
- js进阶 12 jquery事件汇总
js进阶 12 jquery事件汇总 一.常用事件 页面载入事件 ready() 文档就绪事件(当 HTML 文档就绪可用时) 鼠标事件 click() 触发.或将函数绑定到指定元素的 click 事 ...
- CSS进阶内容——布局技巧和细节修饰
CSS进阶内容--布局技巧和细节修饰 我们在之前的文章中已经掌握了CSS的大部分内容,但仍有一些内容我们没有涉略,这篇文章就是为了补充前面没有涉及的内容,为我们的知识做出补充并且介绍一些布局技巧 当然 ...
- MVC进阶讲解+小技巧-乱七八糟
开发步骤 1.建立项目 2.建立文件夹 3.建立Controllers 4.生成页面 5.编写Html+Js 6.编写异步请求的Action的方法,返回部分页(用于分页) 7.Js中显示部分页 8.增 ...
- IOS开发之SWIFT进阶部分
概述 上一篇文章<iOS开发系列--Swift语言> 中对Swift的语法特点以及它和C.ObjC等其他语言的用法区别进行了介绍.当然,这只是Swift的入门基础,但是仅仅了解这些对于使用 ...
随机推荐
- mysql5.6乱码
安装MySql5.6版本遇到一个问题,字符集乱码,如下图 由于是新安装的本地数据库,所以一定是配置的事情,查询数据库字符集配置,如下: show VARIABLES like '%char%'; 有两 ...
- 【原创】菜鸟版Android 笔记1- Android架构和Application
Android架构 图1 Android架构自上而下名称为应用层.应用框架层.运行库和Adroid虚拟机层. Linux内核层. 1. 应用层 应用层像一座大厦里面的砖瓦.我们所做的开发基本上都在应用 ...
- PHP安装加载yaf扩展
Yaf,全称 Yet Another Framework,是一个C语言编写的PHP框架,是一个用PHP扩展形式提供的PHP开发框架, 相比于一般的PHP框架, 它更快. 它提供了Bootstrap, ...
- Servlet 编写过滤器
Servlet 过滤器可以动态地拦截请求和响应,以变换或使用包含在请求或响应中的信息. 可以将一个或多个 Servlet 过滤器附加到一个 Servlet 或一组 Servlet.Servlet 过滤 ...
- python 自动化之路 day 20 Django进阶/BBS项目【一】
一.django进阶 1.django orm 增删改查 1.1.创建表: 1 2 3 >>> from blog.models import Blog >>> b ...
- git 显示多个url地址推送
前提 一般来说,我们为git增加远程库,一般都是git remote add origin <url> ( 你可以使用真实的地址来代替 \<url\> ) 但是你可能想要把你的 ...
- 在MathType中输入罗马数字的方法
MathType作为数学公式编辑器的编辑功能非常的强大,其中包含了许许多多各种各样的数学符号,甚至标记符号也很全面.编辑公式时有时为了让公式看起来会更有条理,会进行一定的序号设置,当然也可以对公式进行 ...
- Jmeter BeanShell 引用变量报错jmeter.util.BeanShellInterpreter: Error invoking bsh method: eval Parse error at line 14, column 181 : Error or number too big for integer
如果你通过CSV Data Set Config或者_StringFromFile函数来参数化你的请求,需要特别注意当参数为纯数字时,jmeter会默认将其识别成int型数据,说明jmeter并不是默 ...
- fork小续
pid_t pid = fork(); 1.根据fork的返回值区分父子进程: fork 函数返回两次, >0 表示父进程,返回值为子进程ID; =0 表示子进程; <0 出错. 可用代码 ...
- keras常用的网络层
一.常用层 常用层对应于core模块,core内部定义了一系列常用的网络层,包括全连接.激活层等. 1.Dense层 Dense层:全连接层. keras.layers.core.Dense(outp ...