這是一份raywenderlich的Swift編程風格指南,中文版由@mrahmiao翻譯,你能夠前往Github訪問這個項目。 javascript
由於該指南關注於網頁上以及打印版的可讀性,因此它可能與你閱讀過的指南有所不一樣。爲了保證那些在咱們書中、教程裏以及初學者工程裏的代碼美觀而且一致,咱們寫下了這份風格指南,儘管書由許多不一樣做者共同創做而成。 java
該指南的首要目標是讓代碼緊湊,可讀性高且簡潔。 node
正在用Objective-C寫程序?也看看咱們的Objective-C風格指南吧。 git
語言 github
使用美式英語拼寫以確保和蘋果公司的API一致。 objective-c
優選: 編程
var color = "red"
不建議使用: swift
var colour = "red"
間隔 安全
使用2個空格而不是Tab進行縮進,能夠減小換行。確保在Xcode的配置項中使用此設置。 閉包
方法的花括號以及其它花括號(if/else/switch/while等等)老是跟語句在同一行開始,新起一行結束。
優選:
if user.isHappy { //Do something } else { //Do something else }
不建議使用:
if user.isHappy { //Do something } else { //Do something else }
方法之間應該老是用一個空行進行分隔以提升視覺以及結構上的清晰度。方法中的空白用來分開功能塊,可是若是一個方法中存在太多功能塊時,一般意味着你須要將它重構爲多個方法。
註釋
在須要的時候使用註釋說明一塊代碼爲何這麼作。註釋必須時刻跟進代碼,否則不如不要。
代碼應該儘量的自文檔化,避免在代碼中使用成塊的註釋。例外:該規則不適用與用於生成文檔的塊註釋。
命名
使用駝峯法爲類、方法、變量等取一個描述性強的名字。模塊範圍的類名和常量名以大寫字母開頭,而方法名和變量名應以小寫字母開頭。
優選:
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 }
對於函數以及初始化方法,除非上下文含義很是清楚,推薦對全部的參數都加以命名。若是外部參數名稱可使得函數調用更易讀,請加上它。
func dateFromString(dateString: NSString) -> NSDate func convertPointAt(#column: Int, #row: Int) -> CGPoint func timedAction(#delay: NSTimeInterval, perform action: SKAction) -> SKAction! // 會被這樣調用 dateFromString("2014-03-14") convertPointAt(column: 42, row: 13) timedAction(delay: 1.0, perform: someOtherAction)
對於方法,遵循蘋果公司的命名規範,在方法名中說起第一個參數:
class Guideline { func combineWithString(incoming: String, options: Dictionary?) { ... } func upvoteBy(amount: Int) { ... } }
在全部說起到函數的內容中(包括教程,書以及評論),請從調用者的視角進行考慮,將全部的必要參數名都包含進來:
dateFromString()函數真是太棒了。 在你的init()方法中調用convertPointAt(column:, row:)。 timedAction(delay:, perform:)的返回值可能爲nil。 Guideline對象只有兩個方法:combineWithString(options:)和upvoteBy()。 你不該該直接調用數據源方法tableView(cellForRowAtIndexPath:)。
類前綴
Swift中的類型會被自動加入包含它們的模塊的命名空間。因此減小命名衝突的前綴已經沒必要要了。若是同模塊的兩個名稱衝突了,能夠在名稱前加上模塊名消除歧義:
import MyModule var myClass = MyModule.MyClass()
不該該給本身建立的Swift類型加前綴。
若是須要把Swift類型暴露給Objective-C使用,你能夠添加一個合適的前綴(前綴的命名請參考Objective-C風格指南):
@objc (RWTChicken) class Chicken { ... }
分號
Swift不要求每條語句後加分號。只有在你想把多條語句寫到一行時才須要加上分號。
請不要在一行中寫上用分號隔開的多條語句。
這條規則的惟一例外就是for-conditional-increment結構,該結構中分號是必需的。不過請儘可能用for-in結構代替它們。
優選:
var swift = "not a scripting language"
不建議使用:
var swift = "not a scripting language";
請注意:Swift與JavaScript不一樣, 在後者中省略分號一般是不安全的。
類與結構體
下面是一個風格良好的類定義代碼例子,請參考:
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 } }
上面的例子闡述了以下的風格準則:
· 給屬性、變量、常量、參數及其它語句指定類型時,在冒號的後面加上空格而不是前面,好比:x: Int跟Circle: Shape。
· 對getter跟setter定義以及屬性觀察器進行縮進。
· 若是多個變量、結構有着一樣的目的或者上下文,在同一行上進行定義。
Self的使用
在Swift中訪問對象屬性或調用方法時不須要使用self,請避免使用它。
使用self的惟一理由是在初始化一個類或結構體時區分屬性名和參數名:
class BoardLocation { let row: Int, column: Int init(row: Int,column: Int) { self.row = row self.column = column } }
函數聲明
保持函數聲明短小精悍,保持在一行內,花括號在同一行內開始:
func reticulateSplines(spline: [Double]) -> Bool { // reticulate code goes here }
對於有着長簽名的函數,請在適當的位置進行斷行且對後續行縮進一級:
func reticulateSplines(spline: [Double], adjustmentFactor: Double, translateConstant: Int, comment: String) -> Bool { // reticulate code goes here }
閉包
儘量地使用尾閉包語法。在全部的狀況下給閉包參數一個描述性強的名稱:
return SKAction.customActionWithDuration(effect.duration) { node, elapsedTime in // more code goes here }
對於上下文清晰的單表達式閉包,使用隱式的返回值:
attendeeList.sort { a, b in a > b }
類型
若是可能,使用Swift的原生類型。Swift提供了對Objective-C的橋接,若是須要,仍然可使用所有的Objective-C方法:
優選:
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能夠避免過多的轉換從而使得代碼簡潔,那麼請使用它。
常量
常量經過let關鍵字定義,而變量使用var關鍵字定義。任何值若是是一個不變量,那麼請使用let關鍵字恰如其分地定義它。最後你會發現本身喜歡使用let遠多於far。
Tip:有一個方法能夠幫你知足該項規則,將全部值都定義成常量,而後編譯器提示的時候將其改成變量。
Optional
在nil值可能出現的狀況下,將變量跟函數返回值的類型經過?定義成Optional。
只有在肯定實例變量會在初始化以後才被使用的狀況下,經過!將其定義爲隱式解包類型(Implicitly Unwrapped Types),好比說會在viewDidLoad中被建立的子視圖。
在訪問一個Optional值時,若是該值只被訪問一次,或者以後須要連續訪問多個Optional值,請使用鏈式Optional語法:
myOptional?.anotherOne?.optionalView?.setNeedsDisplay()
對於須要將Optional值解開一次,而後進行多個操做的狀況,使用Optional綁定更爲方便:
if let view = self.optionalView { // do many things with view }
類型推導
Swift的編譯器能夠推導出變量和常量的類型。能夠顯式地提供類型別名(冒號後面聲明的類型),不過大多數狀況下這都是沒必要要的。
保持代碼緊湊,而後讓編譯器推斷變量跟常量的類型。
優選:
let message = "Click the button" var currentBounds = computeViewBounds()
不建議使用:
let message: String = "Click the button" var currentBounds: CGRect = computeViewBounds()
注意:遵循這條準則意味着使用描述性強的名稱比以前更爲重要了。
語法糖
Prefer the shortcut versions of type declarations over the full generics syntax.
使用簡寫的類型聲明,而不是它的全泛型版本。
優選:
var deviceModels: [String] var employees: [Int: String] var faxNumber: Int?
不建議使用:
var deviceModels: Array var employees: Dictionary var faxNumber: Optional
控制流
對於for循環,優選for-in風格而不是for-condition-increment風格:
優選:
for _ in 0..<3 { println("Hello three times") } for person in attendeeList { // do something }
不建議使用:
for var i = 0; i < 3; i++ { println("Hello three times") } for var i = 0; i < attendeeList.count; i++ { let person = attendeeList[i] // do something }
笑臉
笑臉對於raywenderlich.com來講是一個格外重要的風格特徵。使用正確的笑臉能夠表示出對某個主題的無窮盡的高興以及興奮程度。選用了]是由於它在ASCII藝術能夠表示得最大的笑臉。而閉圓括號)由於給人一種「呵呵」的感受而不建議使用。
優選:
:]
不建議使用:
:)