Swifter - 100 个 Swift 必备 tips,作者[王巍](SWifter - 100个 Swift 必备 tips)。书买了很久了,25元比实体书便宜不少,而且收入基本上都归作者。学习完疯狂 Swift 讲义,再看看这个补充一下。
章节顺序可能与书不一致,全凭兴趣随意浏览,尤其是不太懂得方面。
##操作符
infix 表示一个中位操作符,前后都有输入。类似的还有 prefix 和 postfix。
associativity 定义了结合律
precedence 运算的优先级,Swift 中乘法和除法的优先级是150,加法和减法是140,这里定义160,就是高于普通的四则运算。
操作符定义在全局,不可滥用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| // main.swift // Swift-test
import Foundation
struct Vector2D { var x = 0.0 var y = 0.0 }
func +(left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y) }
let v1 = Vector2D(x: 2.0, y: 3.0) let v2 = Vector2D(x: 1.0, y: 5.0) print(v1 + v2) // Swift_test.Vector2D(x: 3.0, y: 8.0)
infix operator +* { associativity none precedence 160 }
func +*(left: Vector2D, right: Vector2D) -> Double { return left.x * right.x + left.y * right.y }
print(v1 +* v2) // 17.0
|
随机数生成
创建一个 Range 的随机数的方法,方便以后复用。
Swift 支持 // MARK: 、// TODO:、// FIXME:等编译标记,方便分段,将一标签的形式显示在导航栏中,让程序更易读。
1 2 3 4 5 6 7 8 9 10
| // MARK: 实现方法 func randomInRange(range: Range<Int>) -> Int { let count = UInt32(range.endIndex - range.startIndex) return Int(arc4random_uniform(count)) + range.startIndex }
// TODO: 测试是否有效 for _ in 0...100 { print(randomInRange(1...6)) }
|
断言
对于判断输入是否满足某种条件的运用情景,使用断言比 if 更合适。且在 Debug 编译是才有效,运行时不被编译执行,不会消耗运行时的性能。是非常合适的调试判断。
1 2 3 4 5 6 7 8 9 10
| import Foundation
func convertToKelvin( celsius: Double) -> Double { let AbsoluteZeroInCelsius = -273.15 assert(celsius > AbsoluteZeroInCelsius, "输入的摄氏温度不能低于绝对零度。") return celsius - AbsoluteZeroInCelsius }
let roomTemperature = convertToKelvin(27) print(roomTemperature) // 300.15
|
自省
程序设计和人类哲学所面临的同一个重大课程就是解决“我是谁”。
isKindOfClass、isMemberOfClass、is
1 2 3 4 5 6 7 8 9
| class ClassA: NSObject { } class ClassB: NSObject { }
let obj1: NSObject = ClassA() let obj2: NSObject = ClassB()
print(obj1.isKindOfClass(ClassA.self)) // true print(obj2.isMemberOfClass(ClassA.self)) // false
|
属性观察
属性观察可以对当前类型内监视其属性的设定,并作出响应。
1 2 3 4 5 6
| class MyClass {
var date: NSDate {
willSet {
print("即将将日期从 \(date) 设定至 \(newValue)")
}
didSet {
print("已经将日期从 \(oldValue) 设定至 \(date)")
} }
init() {
date = NSDate()
} }
let foo = MyClass()
foo.date = foo.date.dateByAddingTimeInterval(10086)
// 输出
// 即将将日期从 2015-07-16 16:01:49 +0000 设定至 2015-07-16 18:49:55 +0000 // 已经将日期从 2015-07-16 16:01:49 +0000 设定至 2015-07-16 18:49:55 +0000
|