RayWenderlich 官方 Swift 風格指南

該文章由 iOSCaff 社區 組織翻譯,後續社區會保持文章的更新,若是你以爲這篇文章對你有幫助,歡迎到社區點贊支持。javascript

譯文地址:https://ioscaff.com/topics/84/raywenderlich-official-swift-style-guidehtml

原文地址:https://github.com/raywenderlich/swift-style-guidejava

已更新到 Swift 3

這篇風格指南可能不一樣於你看到的其餘風格指南。由於它的重點偏向於打印和網頁的可讀性。咱們建立這篇風格指南的目的,是爲了讓咱們的書、教程和初學者套件中的代碼,在有不少做者同時寫書的狀況下,也能保持規範與一致。ios

咱們的首要目標是清晰、一致和簡潔。git

正確性

努力讓你的代碼在沒有警告的狀況下編譯。 這條規則決定了許多風格決策,好比使用 #selector 類型而不是字符串字面量。github

命名

描述性和一致性的命名讓軟件更易於閱讀和理解。使用 API 設計規範 中描述的 Swift 命名規範。 一些關鍵點包括以下:express

  • 儘可能讓調用的地方更加簡明
  • 簡明性優先而不是簡潔性
  • 使用駝峯命名法(而不是蛇形命名法)
  • 針對類型(和協議)使用首字母大寫,其它都是首字母小寫
  • 包含全部須要的單詞,同時省略沒必要要的單詞
  • 基於角色的命名,而不是類型
  • 有時候要針對弱引用類型信息進行補充
  • 儘可能保持流暢的用法
  • 工廠方法以 make 開頭
  • 命名方法的反作用
    • 不可變版本的動詞方法要遵循後接 -ed, -ing 的規則
    • 可變版本的名詞方法要遵循 formX 的規則
    • 布爾類型應該像斷言同樣讀取
    • 描述 這是什麼 的協議應該讀做名詞
    • 描述 一種能力 的協議應該以 -able 或者 -ible 結尾
  • 使用不會讓專家驚訝或讓初學者迷惑的術語
  • 一般要避免縮寫
  • 使用名稱的先例
  • 首選方法和屬性而不是自由函數
  • 統一貫上或向下包裝首字母縮略詞和首字母
  • 爲相同含義的方法提供相同的基本名稱
  • 避免返回類型的重載
  • 選擇用於文檔的好的參數名
  • 爲閉包和元組參數設置標籤
  • 利用默認參數的優點

文章

在文章中引用方法時,含義明確是相當重要的。儘量用最簡單的形式引用方法。編程

  1. 寫一個不帶參數的方法。 舉例: 下一步,你須要調用方法 addTarget
  2. 寫一個帶參數標籤的方法。 舉例: 下一步,你須要調用方法 addTarget(_:action:)
  3. 寫一個帶參數標籤和類型的完整方法。 舉例: 下一步, 你須要調用方法 addTarget(_: Any?, action: Selector?)

用上面的例子使用 UIGestureRecognizer, 1 是明確的,也是首選的。swift

專家提示: 你能夠用 Xcode 的跳轉欄來查看帶有參數標籤的方法。api

file

類前綴

Swift 的類自動被包含在模塊分配的命名空間中。不該該再添加相似於 RW 的類前綴。若是不一樣模塊的兩個命名衝突,能夠在類名前添加模塊名來消除歧義。不管如何,僅在少數可能引發混淆的狀況下指明模塊名。

import SomeModule

let myClass = MyModule.UsefulClass()
複製代碼

代理

當建立自定義代理方法的時候,未命名的第一個參數應該是代理源。 ( UIKit 包含不少這樣的例子。)

推薦:

func namePickerView(_ namePickerView: NamePickerView, didSelectName name: String)
func namePickerViewShouldReload(_ namePickerView: NamePickerView) -> Bool
複製代碼

不推薦:

func didSelectName(namePicker: NamePickerViewController, name: String)
func namePickerShouldReload() -> Bool
複製代碼

使用上下文推斷的類型

使用上下文推斷編譯器書寫更短更明確的代碼。(你也能夠閱讀 類型推斷。)

推薦:

let selector = #selector(viewDidLoad)
view.backgroundColor = .red
let toView = context.view(forKey: .to)
let view = UIView(frame: .zero)
複製代碼

不推薦:

let selector = #selector(ViewController.viewDidLoad)
view.backgroundColor = UIColor.red
let toView = context.view(forKey: UITransitionContextViewKey.to)
let view = UIView(frame: CGRect.zero)
複製代碼

通常的

通常的類型參數應該是描述性的、大寫駝峯法命名。當類名沒有富有含義的關係或角色時,使用傳統的單個大寫字母來命名,例如 TUV

推薦:

struct Stack<Element> { ... }
func write<Target: OutputStream>(to target: inout Target)
func swap<T>(_ a: inout T, _ b: inout T)
複製代碼

不推薦:

struct Stack<T> { ... }
func write<target: OutputStream>(to target: inout target)
func swap<Thing>(_ a: inout Thing, _ b: inout Thing)
複製代碼

語言

使用美式英語拼寫來匹配 Apple 的 API。

推薦:

let color = "red"
複製代碼

不推薦:

let colour = "red"
複製代碼

代碼組織

用擴展將代碼組織爲功能邏輯塊。每一個擴展都應該添加 // MARK: - 註釋,以保證代碼的結構清晰。

協議遵循

推薦爲協議方法加一個單獨的擴展,尤爲是爲一個模型加入協議遵循的時候。這可讓有關聯的協議方法被分組在一塊兒,也能夠簡化用類關聯方法向這個類添加協議的指令。

推薦:

class MyViewController: UIViewController {
  // 類填充在這
}

// MARK: - UITableViewDataSource
extension MyViewController: UITableViewDataSource {
  // table view 的數據源方法
}

// MARK: - UIScrollViewDelegate
extension MyViewController: UIScrollViewDelegate {
  // scroll view 的代理方法
}
複製代碼

不推薦:

class MyViewController: UIViewController, UITableViewDataSource, UIScrollViewDelegate {
  // 全部方法
}
複製代碼

由於編譯器不容許在派生類中從新聲明協議遵循,因此並不老是須要複製基類的擴展組。若是派生類是一個終端類,而且只有少數方法會被覆蓋,那麼這個原則尤其正確。應由做者自行決定什麼時候保留擴展組- 。

對於 UIKit 中的視圖控制器,可考慮將生命週期、自定義存取器和 IBAction 分組在單獨的類擴展中。

無用代碼

無用代碼(殭屍代碼),包括 Xcode 模板代碼和佔位註釋,應該被移除掉。教程或書籍中教用戶使用的註釋代碼除外。

僅實現簡單調用父類,但與教程無直接關聯的方法應該被移除。這裏包括任何爲空的或無用的 UIApplicationDelegate 方法。

推薦:

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  return Database.contacts.count
}
複製代碼

不推薦:

override func didReceiveMemoryWarning() {
  super.didReceiveMemoryWarning()
  // 任何能夠重建資源的處理。
}

override func numberOfSections(in tableView: UITableView) -> Int {
  // #warning 未完成的實現,返回節數。
  return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  // #warning 未完成的實現,返回行數。
  return Database.contacts.count
}
複製代碼

最小引用

引用最小化。舉個例子,引用 Foundation 就足夠的狀況下不要再引用 UIKit

空格

  • 用兩個字符縮進比用製表符縮進更節省空間,同時能防止換行。務必在 Xcode 和項目中設置這個偏好,以下所示:

file

  • 方法大括號和其餘大括號( if / else / switch / while 等)老是在和語句相同的行寫左括號,而在新行寫右括號。
  • 提示:你能夠經過選中一些代碼(或按 ⌘A 選中所有)而後按 Control-I (或在目錄中選擇編輯器 -> 結構 -> 從新縮進)的方式來從新縮進代碼。一些 Xcode 模板代碼會使用 4 個空格的製表符硬編碼,這就是一個修正它的好方法。 推薦:
if user.isHappy {
  // 作一件事
} else {
  // 作另外一件事
}
複製代碼

不推薦:

if user.isHappy
{
  // 作一件事
}
else {
  // 作另外一件事
}
複製代碼
  • 方法之間應該只有一個空行,這樣有助於視覺清晰和組織。方法中的空白應該按功能分隔代碼,但在一個方法中有不少段意味着你應該將它們封裝進不一樣的方法。
  • 冒號老是在左邊沒有空格而右邊有空格。比較特殊的是三元運算符 ? :、空字典 [:] 和帶有未命名參數 (_:)#selector 語法 .

推薦:

class TestDatabase: Database {
  var data: [String: CGFloat] = ["A": 1.2, "B": 3.2]
}
複製代碼

不推薦:

class TestDatabase : Database {
  var data :[String:CGFloat] = ["A" : 1.2, "B":3.2]
}
複製代碼
  • 長行應該在 70 個字符左右被換行(這裏並不是硬性限制,可自行調整)。
  • 避免在行結尾的地方附上空白。
  • 在每一個文件的結尾處增長一個單獨的換行符。

註釋

須要的時候,用註釋來解釋一個特定的代碼片斷 爲何 作某件事。註釋應保持要麼是最新的,要麼就被刪除。

爲了不塊註釋和代碼內聯,代碼應該儘量自文檔化。 例外:這不含那些註釋被用於生成文檔的狀況 。

類和結構體

使用哪一個?

請記住,結構體有 值語義。對沒有標識的事物應用結構體。一個包含 [a, b, c] 的數組和另外一個包含 [a, b, c] 的數組是徹底同樣的。他們是能夠徹底互換的。使用第一個數組仍是第二個數組都無所謂,由於他們表明着徹底相同的事物。這就是爲何數組是結構體。

類有 引用語義。對有標識或有具體生命週期的事物應用類。你須要將人建模爲一個類,由於不一樣兩我的對象是兩個不一樣的事物。只是由於兩我的擁有相同的名字和生日不意味着他們是同一我的。可是人的生日應該是一個結構體,由於 1950 年 3 月 3 日和任何其它的 1950 年 3 月 3 日日期對象是相同的。日期自己沒有標識。

有時,事物應該是結構體但須要遵循 AnyObject,或在歷史上已經被建模爲類 (NSDateNSSet)。儘量嘗試遵循這些原則。

定義的舉例

這是一個風格良好的類定義例子:

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)
  }

  override func area() -> Double {
    return Double.pi * radius * radius
  }
}

extension Circle: CustomStringConvertible {
  var description: String {
    return "center = \(centerString) area = \(area())"
  }
  private var centerString: String {
    return "(\(x),\(y))"
  }
}
複製代碼

上面的例子遵循瞭如下風格規範:

  • 用後面有空格而前面沒有空格的冒號,爲屬性、變量、常量、參數聲明和其它語句指定類型,例如:x: IntCircle: Shape
  • 若是多個變量和結構體共享一個共同的目的 / 上下文,則能夠在同一行中定義。
  • 縮進 getter、setter 的定義和屬性觀察器。
  • 不要再添加如 internal 的默認修飾符。相似的,當重寫一個方法時,不要再重複添加訪問修飾符。
  • 在擴展中組織額外功能(例如打印)。
  • 隱藏非共享的實現細節,例如 centerString 在擴展中使用 private 訪問控制。

Self 的使用

爲了簡潔,請避免使用 self 關鍵詞,Swift 不須要用它來訪問一個對象屬性或調用它的方法。

僅在編譯器須要時(在 @escaping 閉包或初始化函數中,消除參數與屬性的歧義)才使用 self。換句話說,若是不須要 self 就能編譯經過,則能夠忽略它。

計算屬性

爲了簡潔,若是一個計算屬性是隻讀的,則能夠忽略 get 子句。僅在提供了 set 子句的狀況下才須要 get 子句。

推薦:

var diameter: Double {
  return radius * 2
}
複製代碼

不推薦:

var diameter: Double {
  get {
    return radius * 2
  }
}
複製代碼

Final

在教程中將類或成員標記爲 final 會從主題分散注意力,並且也不必。 儘管如此,final 的使用有時能夠代表你的意圖,且值得你這樣作。在下面的例子中,Box 有特定的目的,且並不打算在派生類中自定義它。標記爲 final 可使它更清晰。

// 用這個 Box 類將任何通常類型轉換爲引用類型。
final class Box<T> {
  let value: T
  init(_ value: T) {
    self.value = value
  }
}
複製代碼

方法聲明

在一行中保持較短的方法聲明,包括左括號:

func reticulateSplines(spline: [Double]) -> Bool {
  // 在這裏寫網格代碼
}
複製代碼

對於簽名較長的函數,則需在合適的位置換行,而後在後續的行中加一個額外的換行:

func reticulateSplines(spline: [Double], adjustmentFactor: Double, translateConstant: Int, comment: String) -> Bool {
  // 在這裏寫網絡代碼
}
複製代碼

閉包表達式

僅在參數列表最後有個單獨的閉包表達式參數時,使用尾隨閉包語法。給閉包參數定義一個描述性的命名。

推薦:

UIView.animate(withDuration: 1.0) {
  self.myView.alpha = 0
}

UIView.animate(withDuration: 1.0, animations: {
  self.myView.alpha = 0
}, completion: { finished in
  self.myView.removeFromSuperview()
})
複製代碼

不推薦:

UIView.animate(withDuration: 1.0, animations: {
  self.myView.alpha = 0
})

UIView.animate(withDuration: 1.0, animations: {
  self.myView.alpha = 0
}) { f in
  self.myView.removeFromSuperview()
}
複製代碼

對於上下文清晰的單獨表達式閉包,使用隱式返回:

attendeeList.sort { a, b in
  a > b
}
複製代碼

使用尾隨閉包的鏈式方法應該清晰且在上下文中易讀。做者將自行抉擇空格、換行、命名與匿名參數的使用。舉例:

let value = numbers.map { $0 * 2 }.filter { $0 % 3 == 0 }.index(of: 90)

let value = numbers
  .map {$0 * 2}
  .filter {$0 > 50}
  .map {$0 + 10}
複製代碼

類型

請儘量多的使用 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 可讓你的代碼避免太多轉換,從而讓你的代碼更加簡潔。

常量

使用 let 關鍵字來定義常量,使用 var 關鍵字來定義變量。若是變量的值不會改變,則要使用 let 來代替 var

提示: 一個比較好的技巧就是定義全部的東西都使用 let , 當編譯器警告的時候再改成 var

你能夠在一個類型裏面去定義常量而不是在類型的實例變量中去使用類型屬性。使用 static let 去聲明一個類型屬性做爲常量。用這種方式聲明類型屬性比聲明全局變量更推薦,由於這種方式更能和實例屬性區分開。舉例:

推薦:

enum Math {
  static let e = 2.718281828459045235360287
  static let root2 = 1.41421356237309504880168872
}

let hypotenuse = side * Math.root2

複製代碼

注意: 使用無大小寫枚舉的優點,就是它不會被意外的實例化,而只是單純的做爲一個命名空間。

不推薦:

let e = 2.718281828459045235360287  // 污染全局命名空間
let root2 = 1.41421356237309504880168872

let hypotenuse = side * root2 // 什麼 root2?
複製代碼

靜態方法和可變類型屬性

靜態方法和類型屬性跟全局函數和全局變量的工做原理相似,應當謹慎使用。當功能的做用域是一個特定類型或須要與 Objective-C 交互時,它們很是有用。

可選類型

在可接受 nil 值的狀況下,使用 ? 聲明變量和函數返回類型爲可選類型。

! 聲明的隱式解包類型,僅用於稍後在使用前初始化的實例變量,好比將在 viewDidLoad 中建立子視圖。

當訪問一個可選值時,若是值僅被訪問一次或在鏈中有許多可選項時,使用可選鏈:

self.textContainer?.textLabel?.setNeedsDisplay()
複製代碼

當一次性解包和執行多個操做更方便時,使用可選綁定:

if let textContainer = self.textContainer {
  // 用 textContainer 作不少事情
}
複製代碼

在命名可選變量和屬性時,需避免相似 optionalStringmaybeView 這樣的命名,由於他們的可選性已經體如今類型聲明中了。

對於可選綁定,適當時使用原始名稱,而不是使用像 unwrappedViewactualLabel 這樣的名稱。

推薦:

var subview: UIView?
var volume: Double?

// later on...
if let subview = subview, let volume = volume {
  // 使用展開的 subview 和 volume 作某件事
}
複製代碼

不推薦:

var optionalSubview: UIView?
var volume: Double?

if let unwrappedSubview = optionalSubview {
  if let realVolume = volume {
    // 使用 unwrappedSubview 和 volume 作某件事
  }
}
複製代碼

延遲初始化

在更細粒度地控制對象聲明週期時考慮使用延遲初始化。 對於UIViewController ,延遲初始化視圖是很是正確的。你也能夠直接調用 { }() 的閉包或調用私有工廠方法。例如:

lazy var locationManager: CLLocationManager = self.makeLocationManager()

private func makeLocationManager() -> CLLocationManager {
  let manager = CLLocationManager()
  manager.desiredAccuracy = kCLLocationAccuracyBest
  manager.delegate = self
  manager.requestAlwaysAuthorization()
  return manager
}
複製代碼

注意:

  • 由於沒有發生循環引用,因此這裏不須要 [unowned self]
  • 位置管理器對彈出 UI 向用戶申請權限有反作用,因此細顆粒地控制在這裏是有意義的。

類型推斷

優先選擇簡潔緊湊的代碼,讓編譯器爲單個實例的常量或變量推斷類型。類型推斷也適合於小(非空)的數組和字典。須要時,請指明特定類型,如 CGFloatInt16

推薦:

let message = "Click the button"
let currentBounds = computeViewBounds()
var names = ["Mic", "Sam", "Christine"]
let maximumWidth: CGFloat = 106.5
複製代碼

不推薦:

let message: String = "Click the button"
let currentBounds: CGRect = computeViewBounds()
let names = [String]()
複製代碼

空數組和空字典的類型註釋

爲空數組和空字典使用類型註釋。(對於分配給大型、多行文字的數組和字典,使用類型註釋。)

推薦:

var names: [String] = []
var lookup: [String: Int] = [:]
複製代碼

不推薦:

var names = [String]()
var lookup = [String: Int]()
複製代碼

注意:遵循此原則意味着選擇描述性命名比以前更重要。

語法糖

推薦使用類型聲明簡短的版本,而不是完整的泛型語法。

推薦:

var deviceModels: [String]
var employees: [Int: String]
var faxNumber: Int?
複製代碼

不推薦:

var deviceModels: Array<String>
var employees: Dictionary<Int, String>
var faxNumber: Optional<Int>
複製代碼

函數 vs 方法

不附屬於類或類型的自有函數應該被謹慎使用。可能的話,首選方法而不是自由函數。這有助於可讀性和易領悟性。

自由函數最適用於它們與任何特定類或實例無關的狀況。

推薦:

let sorted = items.mergeSorted()  // 容易領悟的
rocket.launch()  // 模型的行爲
複製代碼

不推薦:

let sorted = mergeSort(items)  // 難以領悟的
launch(&rocket)
複製代碼

自由函數異常

let tuples = zip(a, b)  // 做爲自由函數感到天然(對稱)
let value = max(x, y, z)  // 另外一個感到天然的自由函數
複製代碼

內存管理

代碼 (甚至非生產環境、教程演示的代碼)都不該該出現循環引用。分析你的對象圖並用 weakunowned 來防止強循環引用。或者,使用值類型( structenum )來完全防止循環引用。

延長對象的生命週期

使用慣用語法 [weak self]guard let strongSelf = self else { return } 來延長對象的生命週期。 在 self 超出閉包生命週期不明顯的地方,[weak self] 更優於 [unowned self]。 明確地延長生命週期優於可選解包。

推薦:

resource.request().onComplete { [weak self] response in
  guard let strongSelf = self else {
    return
  }
  let model = strongSelf.updateModel(response)
  strongSelf.updateUI(model)
}
複製代碼

不推薦:

// 若是在響應返回前 self 被釋放,則可能致使崩潰
resource.request().onComplete { [unowned self] response in
  let model = self.updateModel(response)
  self.updateUI(model)
}
複製代碼

不推薦:

// 內存回收能夠發生在更新模型和更新 UI 之間
resource.request().onComplete { [weak self] response in
  let model = self?.updateModel(response)
  self?.updateUI(model)
}
複製代碼

訪問控制

在教程中,完整的訪問控制註釋會分散主題且是沒必要要的。然而,適時地使用 privatefileprivate 會使代碼更加清晰,也會有助於封裝。 在合理狀況下,private 要優於 fileprivate。 使用擴展可能會要求你使用 fileprivate

只有須要完整的訪問控制規範時,才顯式地使用 openpublicinternal

將訪問控制用做前置屬性說明符。僅有 static 說明符或諸如 @IBAction@IBOutlet@discardableResult 的屬性應該放在訪問控制前面。

推薦:

private let message = "Great Scott!"

class TimeMachine {  
  fileprivate dynamic lazy var fluxCapacitor = FluxCapacitor()
}
複製代碼

不推薦:

fileprivate let message = "Great Scott!"

class TimeMachine {  
  lazy dynamic fileprivate var fluxCapacitor = FluxCapacitor()
}
複製代碼

控制流

優先選擇for 循環的 for-in 格式而不是 while-condition-increment 格式。

推薦:

for _ in 0..<3 {
  print("Hello three times")
}

for (index, person) in attendeeList.enumerated() {
  print("\(person) is at position #\(index)")
}

for index in stride(from: 0, to: items.count, by: 2) {
  print(index)
}

for index in (0...3).reversed() {
  print(index)
}
複製代碼

不推薦:

var i = 0
while i < 3 {
  print("Hello three times")
  i += 1
}


var i = 0
while i < attendeeList.count {
  let person = attendeeList[i]
  print("\(person) is at position #\(i)")
  i += 1
}
複製代碼

黃金路徑

當使用條件語句編碼時,代碼的左邊距應該是 「黃金」或「快樂」的路徑。就是不要嵌套 if 語句。多個返回語句是能夠的。guard語句就是由於這個建立的。

Preferred:

func computeFFT(context: Context?, inputData: InputData?) throws -> Frequencies {

  guard let context = context else {
    throw FFTError.noContext
  }
  guard let inputData = inputData else {
    throw FFTError.noInputData
  }

  // 用上下文和輸入計算頻率
  return frequencies
}
複製代碼

不推薦:

func computeFFT(context: Context?, inputData: InputData?) throws -> Frequencies {

  if let context = context {
    if let inputData = inputData {
      // 用上下文和輸入計算頻率

      return frequencies
    } else {
      throw FFTError.noInputData
    }
  } else {
    throw FFTError.noContext
  }
}
複製代碼

當用 guardif let 解包多個可選值時,在可能的狀況下使用最下化複合版本嵌套。舉例:

推薦:

guard let number1 = number1,
      let number2 = number2,
      let number3 = number3 else {
  fatalError("impossible")
}
// 用數字作某事
複製代碼

不推薦:

if let number1 = number1 {
  if let number2 = number2 {
    if let number3 = number3 {
      // 用數字作某事
    } else {
      fatalError("impossible")
    }
  } else {
    fatalError("impossible")
  }
} else {
  fatalError("impossible")
}
複製代碼

失敗防禦

對於用某些方法退出,防禦語句是必要的。通常地,它應該是一行簡潔的語句,好比: returnthrowbreakcontinuefatalError()。應該避免大的代碼塊。若是清理代碼被用在多個退出點,則能夠考慮用 defer 塊來避免清理代碼的重複。

分號

在 Swift 中,每條代碼語句後面都不須要加分號。只有在你但願在一行中結合多條語句,才須要加分號。

不要在用分號分隔的單行中寫多條語句。

推薦:

let swift = "not a scripting language"
複製代碼

不推薦:

let swift = "not a scripting language";
複製代碼

:Swift 很是不一樣於 JavaScript。在 JavaScript 中忽略分號 通常被認爲不安全

括號

條件周圍的括號是沒必要要的,應該被忽略。

推薦:

if name == "Hello" {
  print("World")
}
複製代碼

不推薦:

if (name == "Hello") {
  print("World")
}
複製代碼

在更大的表達式中,可選括號有時可讓代碼讀起來更清晰。

推薦:

let playerMark = (player == current ? "X" : "O")
複製代碼

組織和包 ID

涉及到 Xcode 項目的地方,組織應該被設置爲 Ray Wenderlich 而且包 ID 應該被設置爲 com.razeware.TutorialName ,其中 TutorialName 是教程項目的名字。

file

版權聲明

如下版權聲明應該被包含在每一個源文件的頂部:

/// Copyright (c) 2018 Razeware LLC
/// 
/// Permission is hereby granted, free of charge, to any person obtaining a copy
/// of this software and associated documentation files (the "Software"), to deal
/// in the Software without restriction, including without limitation the rights
/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
/// copies of the Software, and to permit persons to whom the Software is
/// furnished to do so, subject to the following conditions:
/// 
/// The above copyright notice and this permission notice shall be included in
/// all copies or substantial portions of the Software.
/// 
/// Notwithstanding the foregoing, you may not use, copy, modify, merge, publish,
/// distribute, sublicense, create a derivative work, and/or sell copies of the
/// Software in any work that is designed, intended, or marketed for pedagogical or
/// instructional purposes related to programming, coding, application development,
/// or information technology. Permission for such use, copying, modification,
/// merger, publication, distribution, sublicensing, creation of derivative works,
/// or sale is expressly withheld.
/// 
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
/// THE SOFTWARE.
複製代碼

笑臉

笑臉是網站 raywenderlich.com 很是突出的風格特色!正確使用微笑來表達對編碼主題的歡樂與興奮是很是重要的。使用右方括號 ] 是由於它表明 ASCII 中的最大笑容。右括號 ) 表示三心二意的笑臉,所以不推薦使用。

推薦:

:]
複製代碼

不推薦:

:)
複製代碼

參考文獻


iOSCaff 是一個面向 iOS 開發者的技術知識社區,致力於爲開發者提供一個更加高效、便捷的學習環境。

相關文章
相關標籤/搜索