使用美式英語拼寫以匹配蘋果公司的API
優(yōu)選:
var color = "red"
不建議使用:
var colour = "red"
if
/else
/switch
/while
等等)總是跟語句在同一行開始,但是在新的一行中結(jié)束。優(yōu)選:
if user.isHappy {
//Do something
} else {
//Do something else
}
不建議使用:
if user.isHappy
{
//Do something
}
else {
//Do something else
}
使用駝峰法為類、方法、變量等等取一個(gè)描述性強(qiáng)的名字。模塊范圍的類名以及常量名稱要以大寫字母開頭,而方法名跟變量名則應(yīng)該以小寫字母開頭。
優(yōu)選:
let MaximumWidgetCount = 100
class WidgetContainer {
var widgetButton: UIButton
let widgetHeightPercentage = 0.85
}
不建議使用:
let MAX_WIDGET_COUNT = 100
class app_widgetContainer {
var wBut: UIButton
let wHeightPct = 0.85
}
對(duì)于普通函數(shù)以及構(gòu)造函數(shù)名稱,除非上下文含義非常清楚,對(duì)所有的參數(shù)都加以命名是更為推薦的做法。如果外部參數(shù)名稱可以使得函數(shù)調(diào)用更具有可讀性,那么請(qǐng)帶上它。
func dateFromString(dateString: NSString) -> NSDate
func convertPointAt(#column: Int, #row: Int) -> CGPoint
func timedAction(#delay: NSTimeInterval, perform action: SKAction) -> SKAction!
// 會(huì)被這樣調(diào)用
dateFromString("2014-03-14")
convertPointAt(column: 42, row: 13)
timedAction(delay: 1.0, perform: someOtherAction)
對(duì)于方法,遵循蘋果公司的命名標(biāo)準(zhǔn),在方法名中提及第一個(gè)參數(shù):
class Guideline {
func combineWithString(incoming: String, options: Dictionary?) { ... }
func upvoteBy(amount: Int) { ... }
}
在所有提及到函數(shù)的內(nèi)容中(包括教程,書以及評(píng)論),請(qǐng)從調(diào)用者的視角進(jìn)行考慮,將所有的必要參數(shù)名都包含進(jìn)來:
dateFromString()函數(shù)真是太棒了。
在你的init()方法中調(diào)用convertPointAt(column:, row:)。
timedAction(delay:, perform:)的返回值可能為nil。
Guideline對(duì)象只有兩個(gè)方法:combineWithString(options:)跟upvoteBy()。
你不應(yīng)該直接調(diào)用數(shù)據(jù)源方法tableView(cellForRowAtIndexPath:)。
Swift中的類型會(huì)自動(dòng)加入包含它們的模塊的命名空間。所以即使是為了最小化命名沖突的可能性,前綴也是不必要的。如果來自于不同模塊的兩個(gè)名稱沖突了,可以通過在名稱前面加上模塊名以消除歧義:
import MyModule
var myClass = MyModule.MyClass()
不應(yīng)該在自己創(chuàng)建的類型上加前綴。
如果需要將Swift類型暴露在Objective-C環(huán)境中使用,請(qǐng)按照以下方式提供合適的前綴(前綴的命名請(qǐng)參考Objective-C風(fēng)格指南):
@objc (RWTChicken) class Chicken {
...
}
Swift中,每條語句后的分號(hào)都不是必需的。只有在一行中有多條語句時(shí)才需要添加上分號(hào)。
請(qǐng)不要在一行中寫上用分號(hào)隔開的多條語句。
這條規(guī)則的唯一例外就是for-conditional-increment
結(jié)構(gòu),該結(jié)構(gòu)中分號(hào)是必需的。不過,請(qǐng)盡可能地使用另外一種結(jié)構(gòu),for-in
循環(huán)。
優(yōu)選:
var swift = "not a scripting language"
不建議使用:
var swift = "not a scripting language";
請(qǐng)注意:Swift與JavaScript不同, 在后者中省略分號(hào)通常是不安全的。
下面的代碼是一個(gè)很有標(biāo)準(zhǔn)范兒的類定義,請(qǐng)參考:
class Circle: Shape {
var x: Int, y: Int
var radius: Double
var diameter: Double {
get {
return radius * 2
}
set {
radius = newValue / 2
}
}
init(x: Int, y: Int, radius: Double) {
self.x = x
self.y = y
self.radius = radius
}
convenience init(x: Int, y: Int, diameter: Double) {
self.init(x: x, y: y, radius: diameter / 2)
}
func describe() -> String {
return "I am a circle at (\(x),\(y)) with an area of \(computeArea())"
}
func computeArea() -> Double {
return M_PI * radius * radius
}
}
上面的例子闡述了這么幾個(gè)風(fēng)格上的準(zhǔn)則:
x: Int
跟Circle: Shape
。考慮到在Swift中訪問一個(gè)對(duì)象的屬性或者調(diào)用它的方法并不需要使用self
,所以請(qǐng)避免使用它。
需要使用self
的唯一理由就是在初始化一個(gè)類或者結(jié)構(gòu)體時(shí),使用其在屬性名和參數(shù)之間加以區(qū)分:
class BoardLocation {
let row: Int, column: Int
init(row: Int,column: Int) {
self.row = row
self.column = column
}
}
保持函數(shù)聲明短小精悍,盡量在一行中完成聲明,同時(shí)還包含了開括號(hào):
func reticulateSplines(spline: Double[]) -> Bool {
// reticulate code goes here
}
對(duì)于有著長長的參數(shù)的函數(shù),請(qǐng)?jiān)谶m當(dāng)?shù)奈恢眠M(jìn)行斷行且對(duì)后續(xù)行縮進(jìn)一級(jí):
func reticulateSplines(spline: Double[], adjustmentFactor: Double,
translateConstant: Int, comment: String) -> Bool {
// reticulate code goes here
}
盡可能地使用尾閉包語法。在所有的情況下都需要給閉包參數(shù)一個(gè)描述性強(qiáng)的名稱:
return SKAction.customActionWithDuration(effect.duration) { node, elapsedTime in
// more code goes here
}
對(duì)于上下文清晰的單表達(dá)式閉包,使用隱式的返回值:
attendeeList.sort { a, b in
a > b
}
盡可能地使用Swift原生類型。Swift提供了對(duì)Objective-C的橋接所以在需要的時(shí)候仍然可以使用全部的Objective-C方法:
優(yōu)選:
let width = 120.0 //Double
let widthString = width.bridgeToObjectiveC().stringValue //String
不建議使用:
let width: NSNumber = 120.0 //NSNumber
let widthString: NSString = width.stringValue //NSString
在Sprite Kit的代碼中,如果CGFloat
可以避免過多的轉(zhuǎn)換而使得代碼簡潔明了,那么請(qǐng)用上它。
常量通過let
關(guān)鍵字定義,而變量使用var
關(guān)鍵字定義。任何值如果是一個(gè)不變量,那么請(qǐng)使用let
關(guān)鍵字恰如其分地定義它。最后你會(huì)發(fā)現(xiàn)自己喜歡使用let
遠(yuǎn)多于far
。
Tip:有一個(gè)方法可以幫你符合該項(xiàng)規(guī)則,將所有值都定義成常量,然后編譯器提示的時(shí)候?qū)⑵涓臑樽兞俊?/p>
在nil值可能出現(xiàn)的情況下,將變量跟函數(shù)返回值的類型通過?
定義成Optional。
只有在確定實(shí)例變量會(huì)在初始化之后才被使用的情況下,通過!
將其定義為隱式解包類型(Implicitly Unwrapped Types),比如說會(huì)在viewDidLoad
中被創(chuàng)建的子視圖。
在訪問一個(gè)Optional值時(shí),如果該值只被訪問一次,或者之后需要連續(xù)訪問多個(gè)Optional值,請(qǐng)使用鏈?zhǔn)絆ptional語法:
myOptional?.anotherOne?.optionalView?.setNeedsDisplay()
對(duì)于需要將Optional值解開一次,然后進(jìn)行多個(gè)操作的情況,使用Optional綁定更為方便:
if let view = self.optionalView {
// do many things with view
}
Swift的編譯器可以推斷出變量跟常量的類型??梢酝ㄟ^類型別名(在冒號(hào)后面指出其類型)提供顯式類型,不過大多數(shù)情況下這都是不必要的。
保持代碼緊湊,然后讓編譯器推斷變量跟常量的類型。
優(yōu)選:
let message = "Click the button"
var currentBounds = computeViewBounds()
不建議使用:
let message: String = "Click the button"
var currentBounds: CGRect = computeViewBounds()
注意:遵循這條準(zhǔn)則意味著描述性強(qiáng)的名稱比之前更為重要了。
對(duì)于for
循環(huán),優(yōu)選for-in
風(fēng)格而不是for-condition-increment
風(fēng)格:
優(yōu)選:
for _ in 0..5 {
println("Hello five times")
}
for person in attendeeList {
// do something
}
不建議使用:
for var i = 0; i < 5; i++ {
println("Hello five times")
}
for var i = 0; i < attendeeList.count; i++ {
let person = attendeeList[i]
// do something
}
笑臉對(duì)于raywenderlich.com來說是一個(gè)格外重要的風(fēng)格特征。使用正確的笑臉可以表示出對(duì)某個(gè)主題的無窮盡的高興以及興奮程度。選用了]
是因?yàn)樗贏SCII藝術(shù)可以表示得最大的笑臉。而閉圓括號(hào))
因?yàn)榻o人一種“呵呵”的感覺而不建議使用。
優(yōu)選:
:]
不建議使用:
:)
本風(fēng)格指南的目標(biāo)是讓Swift代碼更簡潔、可讀更強(qiáng)。
更多建議: