## 类型(Types)
尽可能使用 Swift 原生类型。Swift 提供到 Objective-C 类型的桥接,所以你仍然可以使用许多需要的方法。
推荐做法:
~~~
let width = 120.0 // Double
let widthString = (width as NSNumber).stringValue // String
~~~
不推荐做法:
~~~
let width: NSNumber = 120.0 // NSNumber
let widthString: NSString = width.stringValue // NSString
~~~
在 Sprite Kit 代码中,使用 CGFloat 可以使得代码更加简明,避免很多转换。
### 常量(Constants)
常量定义使用 `let` 关键字,变量定义使用 `var` 关键字,如果变量的值不需要改变,请尽量使用 `let` 关键字。
提示:一个好的技巧是,使用 `let` 定义任何东西,只有在编译器告诉我们值需要改变的时候才改成 `var` 定义。
### 可选类型(Optionals)
当nil值是可以接受的时候时,定义变量和函数返回值为可选类型(?)。
当你确认变量在使用前已经被初始化时,使用!来显式的拆包类型,比如在`viewDidLoad`中会初始化`subviews`。
当你访问一个可选值时,如果只需要访问一次或者在可选值链中有多个可选值时,请使用可选值链:
~~~
self.textContainer?.textLabel?.setNeedsDisplay()
~~~
当需要很方便的一次性拆包或者添加附加的操作时,请使用可选值绑定:
~~~
if let textContainer = self.textContainer {
// do many things with textContainer
}
~~~
当我们命名一个可选变量和属性时,避免使用诸如`optionalString`和`maybeView`这样的命名,因为可选值的表达已经在类型定义中了。
在可选值绑定中,直接映射原始的命名比使用诸如`unwrappedView`和`actualLabel`要好。
推荐做法:
~~~
var subview: UIView?
var volume: Double?
// later on...
if let subview = subview, volume = volume {
// do something with unwrapped subview and volume
}
~~~
不推荐做法:
~~~
var optionalSubview: UIView?
var volume: Double?
if let unwrappedSubview = optionalSubview {
if let realVolume = volume {
// do something with unwrappedSubview and realVolume
}
}
~~~
### 结构体构造器(Struct Initializers)
使用原生的 Swift 结构体构造器,比老式的几何类(CGGeometry)的构造器要好。
推荐做法:
~~~
let bounds = CGRect(x: 40, y: 20, width: 120, height: 80)
let centerPoint = CGPoint(x: 96, y: 42)
~~~
不推荐做法:
~~~
let bounds = CGRectMake(40, 20, 120, 80)
let centerPoint = CGPointMake(96, 42)
~~~
推荐使用结构体限定的常量`CGRect.infiniteRect`,`CGRect.nullRect`等,来替代全局常量`CGRectInfinite`,`CGRectNull`等。对于已经存在的变量,可以直接简写成 `.zeroRect`。
### 类型推断(Type Inference)
推荐使用更加紧凑的代码,让编译器能够推断出常量和变量的类型。除非你需要定义一个特定的类型(比如`CGFloat`和`Int16`),而不是默认的类型。
推荐做法:
~~~
let message = "Click the button"
let currentBounds = computeViewBounds()
var names = [String]()
let maximumWidth: CGFloat = 106.5
~~~
不推荐做法:
~~~
let message: String = "Click the button"
let currentBounds: CGRect = computeViewBounds()
var names: [String] = []
~~~
注意:遵守这条规则意味选择描述性命名比之前变得更加重要。
### 语法糖(Syntactic Sugar)
推荐使用类型定义简洁的版本,而不是全称通用语法。
推荐做法:
~~~
var deviceModels: [String]
var employees: [Int: String]
var faxNumber: Int?
~~~
不推荐做法:
~~~
var deviceModels: Array<String>
var employees: Dictionary<Int, String>
var faxNumber: Optional<Int>
~~~