raywenderlich.com的Swift編程風格指南

來源:互聯網
上載者:User

標籤:結構   成員   his   line   let   case   tor   script   eth   

翻譯自:https://github.com/raywenderlich/swift-style-guide

這個風格指南可能和你從其它地方看到的不同,我們的焦點主要集中在互連網和文章上的可讀性。建立這個編程風格指南是為了保持我們的書籍、教程和入門工具包中代碼的優雅與一致性------雖然我們有和很多不同的作者合作。

我們的首要目的是簡潔、可讀性和簡單。

你在寫Objective-C嗎?看看我們的Objective-C風格指南吧。 

檔案夾
命名對類、方法、變數等使用包括描寫敘述性的駝峰式(CamelCase)命名。類名和全域常量的全部首字母大寫,方法和變數名開始第一個字母小寫。建議:
let MaximumWidgetCount = 100class WidgetContainer {  var widgetButton: UIButton  let widgetHeightPercentage = 0.85}
不建議:
let MAX_WIDGET_COUNT = 100class app_widgetContainer {  var wBut: UIButton  let wHeightPct = 0.85}
對於函數和init方法,全部的參數都要擁有一個有著良好命名的參數名,除非上下文已經非常清晰了。假設在外部調用函數的時候包括了參數名,將會使函數調用更加易讀:
func dateFromString(dateString: NSString) -> NSDatefunc convertPointAt(column: Int, row: Int) -> CGPointfunc timedAction(delay: NSTimeInterval, perform action: SKAction) -> SKAction!// would be called like this:dateFromString("2014-03-14")convertPointAt(column: 42, row: 13)timedAction(delay: 1.0, perform: someOtherAction)
對於方法而言。依照Apple的習慣,在方法名裡引用第一個參數:
class Guideline {  func combineWithString(incoming: String, options: Dictionary?) { ... }  func upvoteBy(amount: Int) { ... }}
當我們在文章中須要引用方法的地方,要從調用者的角度包括全部必須的參數名。假設上下文非常清晰。並且準確的方法簽名不重要時。你就能僅僅用法名。

從你自己的init方法實現中調用convertPointAt(column:row:)

假設你實現了didSelectRowAtIndexPath,那麼記得在你完畢工作後取消選擇行。

你不能直接調用dataSource的tableView(_:cellForRowAtIndexPath:)
類首碼Swift的類型都自己主動的有其模組的命名空間,其結果是不用為了降低名稱衝突而必須使用首碼。假設有兩個來自於不同模組的名稱起了衝突,你能夠通過在類型名稱前加上模組名來消除兩者間的歧義:
import MyModulevar myClass = MyModule.MyClass()
不應該為Swift類型加上首碼。假設你須要暴露一個Swift類型在Objective-C裡使用,你也能提供一個合適的首碼,就像以下這樣:
@objc (RWTChicken) class Chicken {   ...}

間隔
  • 使用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}
  • 在方法之間應該正好有一個空行。這能使結構看起來更加清晰。

    在方法內用空行分隔功能。但假設分隔成太多段的話,經常意味著你須要把一個方法重構成多個方法。


凝視在須要的時候。用凝視來解釋一段特殊的代碼 為什麼要這麼做,凝視必須保持更新或者乾脆刪掉。避免在代碼裡嵌入大塊凝視,應該讓代碼本身作為自己的文檔。 例外:這不適用於那些通過凝視來產生文檔的情況。


類和結構體這裡有一個風格非常好的定義類的範例:
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 \(centerString()) with an area of \(computeArea())"  }  override func computeArea() -> Double {    return M_PI * radius * radius  }  private func centerString() -> String {    return "(\(x),\(y))"  }}
上面的這個範例清晰地展示了以下規則:
  • 為屬性、變數、常量、參數定義以及其它申明指定類型的時候,在冒號後面而不是前面添加一個空格,比方:x: Int 和 Circle: Shape。
  • 對於多個變數,假設它們有相同的結構和上下文環境(比方x、y),則把它們定義在同一行。
  • 縮排屬性(property)的getter/setter定義。
  • 不要加入像interal這種預設修飾符。相同的,當覆蓋一個方法時。不要在方法上再次寫上它的訪問修飾符。
Self的使用避免使用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}

閉包儘可能地使用跟隨閉包文法(Trailing Closure Syntax)。

在不論什麼情況下,給閉包中的參數具有描寫敘述性的名稱:

return SKAction.customActionWithDuration(effect.duration) { node, elapsedTime in   // more code goes here}
對上下文清晰的單行運算式閉包,使用隱式的return:
attendeeList.sort { a, b in  a > b}

類型假設可能的話, 總是使用Swift的原生類型。

Swift提供了橋接(Bridging)到Objective-C的功能,在須要時你也能使用Objective-C的完整方法:

建議:
let width = 120.0                                    //Doublelet widthString = (width as NSNumber).stringValue    //String
不建議:
let width: NSNumber = 120.0                                 //NSNumberlet widthString: NSString = width.stringValue               //NSString
在使用Sprite Kit的代碼裡,使用CGFloat能使代碼更加簡潔,同一時候能避免太多的類型轉換。


常量常量使用letkeyword定義,變數使用varkeyword定義。用let適當地定義那些永遠不會被改動的值。你可能會因此發現你自己用let遠超過用var。 提示:一個技巧能協助我們達到這個標準:把全部的東西都定義成常量,僅僅有當編譯器報錯時才將其替換為變數。
Optional用?定義變數和方法的傳回值為optional。表示該值能夠接受nil。假設你知道一個執行個體變數一定會在使用前被初始化,如viewDidLoad方法裡會設定全部的子視圖,你就能用 ! 對這個變數做隱式的拆包。當訪問一個optional的值時,假設該值僅僅訪問一次,或者有太多的optioanl值關聯。那麼就用Optional Chaining:
myOptional?

.anotherOne?.optionalView?.setNeedsDisplay()

假設想更方便的做一次拆包然後運行多個操作。用Optional Binding:
if let view = self.optionalView {  // do many things with view}

結構體的初始化使用Swift原生的結構體初始化方式比曾經的CGGeometry構造方式要好。建議:
let bounds = CGRect(x: 40, y: 20, width: 120, height: 80)var centerPoint = CGPoint(x: 96, y: 42)
不建議:
let bounds = CGRectMake(40, 20, 120, 80)var centerPoint = CGPointMake(96, 42)

類型判斷Swift編譯器能夠判斷出變數和常量的資料類型。你能夠通過提供類型別名(就是冒號後面的)來顯式聲明資料類型。但大多數情況下不須要這麼做。

我們喜歡簡明扼要的代碼。讓編譯器去判斷變數和常量的類型吧。(在某些情況下可能須要顯式聲明,比方你對一個變數賦一個浮點型,Swift會將這個變數判斷為double。而不是float,假設你一定要用float,就僅僅能顯式聲明了)
建議:
let message = "Click the button"var currentBounds = computeViewBounds()
不建議:
let message: String = "Click the button"var currentBounds: CGRect = computeViewBounds()
備忘:依照本原則:取一個具有描寫敘述性的名字比什麼都要重要。
文法糖定義泛型型別時使用捷徑比使用完整文法要更好。

建議:
var deviceModels: [String]var employees: [Int: String]var faxNumber: Int?

不建議:
var deviceModels: Array<String>var employees: Dictionary<Int, String>var faxNumber: Optional<Int>

控制流程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}

分號Swift不再須要你的每一行代碼後面加上分號,僅僅要當你想把多條語句放在同一行的時候才是必須的。不要把多條語句用分號分隔寫在一行。

僅僅有一種例外情況:構造for-condition-increment的時候必須用分號。然而,儘可能地使用for-in迴圈。

建議:
var swift = "not a scripting language"
不建議:
var swift = "not a scripting language";
備忘:Swift與JavaScript有非常大不同,在JavaScript裡省略分號通常被覺得是不安全的。
語言使用美式英語去適應Apple的API。建議:
var color = "red"
不建議:
var colour = "red"

笑臉笑臉是raywenderlick.com網站非常突出的特色功能。正確的笑臉意味著對編程有著無比的快樂與興奮。這是非常重要的。使用右方括弧]代表了能被ASCII Art記錄的最大的微笑。而右括弧)表示建立了一個半心半意的笑臉,因此這是不可取的。

建議:
:]
不建議:
:)

功臣這份風格指南是最時尚的raywenderlich.com團隊成員們努力協作的成果:
  • Soheil Moayedi Azarpour
  • Scott Berrevoets
  • Eric Cerney
  • Sam Davies
  • Evan Dekhayser
  • Jean-Pierre Distler
  • Colin Eberhardt
  • Greg Heo
  • Matthijs Hollemans
  • Erik Kerber
  • Christopher LaPollo
  • Andy Pereira
  • Ryan Nystrom
  • Cesare Rocchi
  • Ellen Shapiro
  • Marin Todorov
  • Chris Wagner
  • Ray Wenderlich
  • Jack Wu
向Nicholas Waynik和Objective-C風格指南的團隊致敬!

我們的靈感來自於蘋果的Swift參考材料:
  • The Swift Programming Language
  • Using Swift with Cocoa and Objective-C
  • Swift Standard Library Reference

raywenderlich.com的Swift編程風格指南

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.