Swift編碼規范

從其他地方整理了一些編碼規范的資料,分享給大家。YoY

這我們的首要目標是簡潔,可讀性和簡單性。

1.命名(Naming)

使用駝峰命名規則和描述性的名稱來定義類、方法、變量等。類名和模塊中的常量的第一個字母應該大寫,而方法名和變量應該開始用小寫字母。
Use descriptive names with camel case for classes, methods, variables, etc. Class names and constants in module scope should be capitalized, while method names and variables should start with a lower case letter.

Preferred:
let MaximumWidgetCount = 100
class WidgetContainer {
   var widgetButton: UIButton  
let widgetHeightPercentage = 0.85
}
Not Preferred:
let MAX_WIDGET_COUNT = 100
class app_widgetContainer {  
    var wBut: UIButton  
    let wHeightPct = 0.85
}

對于方法和init函數,需要對所有參數進行命名除非上下文是非常清楚的。包括外部的參數名稱,如果它使函數調用更具可讀性。
For functions and init methods, prefer named parameters for all arguments unless the context is very clear. Include external parameter names if it makes function calls more readable.

func dateFromString(dateString: NSString) -> NSDate
func convertPointAt(#column: Int, #row: Int) -> CGPoint
func 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)

對于方法,按照蘋果關于方法第一個參數的標準:
For methods, follow the standard Apple convention of referring to the first parameter in the method name:

class Guideline {  
    func combineWithString(incoming: String, options: Dictionary?) {
        ... 
    }  
   func upvoteBy(amount: Int) { 
       ... 
    }
}

當在文章中(教程,書籍,評論)包含函數代碼是,需要從調用者的角度考慮所需要的參數名稱。如果上下文是明確的,確切的簽名并不重要,你可以只使用方法名。
When referring to functions in prose (tutorials, books, comments) include the required parameter names from the caller's perspective. If the context is clear and the exact signature is not important, you can use just the method name.
Call convertPointAt(column:row:) from your own init implementation.
If you implement didSelectRowAtIndexPath, remember to deselect the row when you're done.
You shouldn't call the data source method tableView(_:cellForRowAtIndexPath:) directly.

2.類前綴(Class Prefixes)

Swift會自動為模塊中的類型增加命名空間。因此,不需要為避免名字沖突為類型增加前綴。如果不同模塊的兩個名字有沖突,那么可以通過模塊名來解決合格問題。
Swift types are all automatically namespaced by the module that contains them. As a result, prefixes are not required in order to minimize naming collisions. If two names from different modules collide you can disambiguate by prefixing the type name with the module name:

import MyModulevar myClass = MyModule.MyClass()

你不需要為你的Swift類型增加前綴

You should not add prefixes to your Swift types.

如果你需要編寫在Objective-C中使用的Swift類型,你可以各一個適當的前綴

@objc (RWTChicken) class Chicken {   
    ...
}

3.空白(Spacing)

? 使用縮進2個空格,而不是制表符,以節省空間,并有助于防止換行。請務必在Xcode中設置此偏好。
Indent using 2 spaces rather than tabs to conserve space and help prevent line wrapping. Be sure to set this preference in Xcode.
? 方法括號和大括號等(if/else/switch/while等)總是在同一行語句打開在新行關閉。

Method braces and other braces (if/else/switch/while etc.) always open on the same line as the statement but close on a new line.
Preferred:
if user.isHappy {
  //Do something
} else {
 //Do something else
}
Not Preferred:
if user.isHappy
{
    //Do something
}
else {
    //Do something else
}

? 為了閱讀方便應該在方法之間保持一個空行以更好的組織代碼。在方法中空行應該分割功能塊,但如果一個方法有太多的功能塊,那么通常意味著你應該重構到多個方法中。

    There should be exactly one blank line between methods to aid in visual clarity and organization. Whitespace within methods should separate functionality, but having too many sections in a method often means you should refactor into several methods.

4.注釋(Comments)

當需要的時候,使用注釋來解釋特定代碼的功能,注釋必須保持最新或刪除。避免在代碼塊內的大塊注釋,該代碼應該是自我描述的。例外:這并不適用于那些用來生成文檔的注釋。
When they are needed, use comments to explain why a particular piece of code does something. Comments must be kept up-to-date or deleted.
Avoid block comments inline with code, as the code should be as self-documenting as possible. Exception: This does not apply to those comments used to generate documentation.

5.類和結構(Classes and Structures)

下面是一個較好的類定義格式
Here's an example of a well-styled class definition:

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

上面的示例提供了較好的編碼規范指南:
The example above demonstrates the following style guidelines:
? 屬性,變量,常量,參數的類型和分號之間保持一個空格,如:x: Int 和 Circle: Shape

Specify
types for properties, variables, constants, argument declarations and other statements with a space after the colon but not before, e.g. x: Int, and Circle: Shape.
? 如果多個變量和結構擁有相同的目的或上下文,那么在一行里定義他們

    Define multiple variables and structures on a single line if they share a common purpose / context.

? 縮進getter、setter方法和屬性觀察器

        Indent getter and setter definitions and property observers.

? 不需要增加默認修飾比如internal。同樣,覆蓋的方法時,不要重復添加訪問修飾符。

    Don't add modifiers such as internal when they're already the default. Similarly, don't repeat the access modifier when overriding a method.

6.使用self(Use of Self)

為了簡潔,避免使用self因為Swift并不需要用它來訪問對象的屬性或調用其方法。
For conciseness, avoid using self since Swift does not require it to access an object's properties or invoke its methods.
當需要在初始化代碼中區分屬性名稱和參數以及在閉包中明確引用屬性時使用self:
Use self when required to differentiate between property names and arguments in initializers, and when referencing properties in closures to make capture semantics explicit:

class BoardLocation {
  let row: Int, column: Int

  init(row: Int,column: Int) {
    self.row = row
    self.column = column
    let closure = { () -> () in
      println(self.row)
    }
  }
}

7.定義函數(Function Declarations)

對于較短的函數定義,需要在一行中定義:
Keep short function declarations on one line including the opening brace:

 func reticulateSplines(spline: [Double]) -> Bool {
  // reticulate code goes here
}

對于有很長簽名的函數,需要在適當的位置添加換行并且新行需要有額外的縮進。
For functions with long signatures, add line breaks at appropriate points and add an extra indent on subsequent lines:

func reticulateSplines(spline: [Double], adjustmentFactor: Double,
    translateConstant: Int, comment: String) -> Bool {
  // reticulate code goes here
}

8.閉包(Closures)

盡可能使用后關閉語法。在所有情況下,閉包的參數需要有一個描述性的名稱:
Use trailing closure syntax wherever possible. In all cases, give the closure parameters descriptive names:

return SKAction.customActionWithDuration(effect.duration) { node, elapsedTime in 
// more code goes here
}

對于只有一行表達式的閉包,如果上下文清晰的話可以隱式返回。
For single-expression closures where the context is clear, use implicit returns:

attendeeList.sort { a, b in
  a > b
}

8.類型(Types)

盡可能地使用Swift原生類型。Swift提供了對Objective-C的橋接所以在需要的時候仍然可以使用全部的Objective-C方法:
Always use Swift's native types when available. Swift offers bridging to Objective-C so you can still use the full set of methods as needed.

Preferred:
let width = 120.0                                    //Double
let widthString = (width as NSNumber).stringValue    //String
Not Preferred:
let width: NSNumber = 120.0                                 //NSNumber
let widthString: NSString = width.stringValue               //NSString

在Sprite Kit代碼中,使用CGFloat,如果它使代碼更簡潔,避免過多的轉換。
In Sprite Kit code, use CGFloat if it makes the code more succinct by avoiding too many conversions.

9.常量(Constants)

常量通過let關鍵字定義,而變量使用var關鍵字定義。任何值如果是一個不變量,那么請使用let關鍵字恰如其分地定義它。最后你會發現自己喜歡使用let遠多于far。
Constants are defined using the let keyword, and variables with the var keyword. Any value that is a constant must be defined appropriately, using the let keyword. As a result, you will likely find yourself using let far more than var.
Tip:有一個方法可以幫你符合該項規則,將所有值都定義成常量,然后編譯器提示的時候將其改為變量。
Tip: One technique that might help meet this standard is to define everything as a constant and only change it to a variable when the compiler complains!

可選的(Optionals)

在nil值可能出現的情況下,將變量跟函數返回值的類型通過?定義成Optional。
Declare variables and function return types as optional with ? where a nil value is acceptable.
只有在確定實例變量會在初始化之后才被使用的情況下,通過 ! 將其定義為隱式解包類型(Implicitly Unwrapped Types),比如說會在viewDidLoad中被創建的子視圖。
Use implicitly unwrapped types declared with ! only for instance variables that you know will be initialized later before use, such as subviews that will be set up in viewDidLoad.
在訪問一個Optional值時,如果該值只被訪問一次,或者之后需要連續訪問多個Optional值,請使用鏈式Optional語法:
When accessing an optional value, use optional chaining if the value is only accessed once or if there are many optionals in the chain:

myOptional?.anotherOne?.optionalView?.setNeedsDisplay()

對于需要將Optional值解開一次,然后進行多個操作的情況,使用Optional綁定更為方便:
Use optional binding when it's more convenient to unwrap once and perform multiple operations:

if let view = self.optionalView {
  // do many things with view
}

10.初始化結構體(Struct Initializers)

使用Swift原生的結構體初始化方法,而不是使用陳舊的CGGeometry構造方法
Use the native Swift struct initializers rather than the legacy CGGeometry constructors.

Preferred:
let bounds = CGRect(x: 40, y: 20, width: 120, height: 80)
var centerPoint = CGPoint(x: 96, y: 42)
Not Preferred:
let bounds = CGRectMake(40, 20, 120, 80)
var centerPoint = CGPointMake(96, 42)

11.類型推斷(Type Inference)

Swift的編譯器可以推斷出變量跟常量的類型。可以通過類型別名(在冒號后面指出其類型)提供顯式類型,不過大多數情況下這都是不必要的。
The Swift compiler is able to infer the type of variables and constants. You can provide an explicit type via a type alias (which is indicated by the type after the colon), but in the majority of cases this is not necessary.
保持代碼緊湊,然后讓編譯器推斷變量跟常量的類型。
Prefer compact code and let the compiler infer the type for a constant or variable.

Preferred:
let message = "Click the button"
var currentBounds = computeViewBounds()
Not Preferred:
let message: String = "Click the button"
var currentBounds: CGRect = computeViewBounds()

注意:遵循這條準則意味著描述性強的名稱比之前更為重要了。
NOTE: Following this guideline means picking descriptive names is even more important than before.

12.語法糖(Syntactic Sugar)

使用類型定義個快捷語法而不要使用完整的語法
Prefer the shortcut versions of type declarations over the full generics syntax.

Preferred:
var deviceModels: [String]
var employees: [Int: String]
var faxNumber: Int?
Not Preferred:
var deviceModels: Array<String>
var employees: Dictionary<Int, String>
var faxNumber: Optional<Int>
13.控制流(Control Flow)

對于for循環,優選for-in風格而不是for-condition-increment風格
Prefer the for-in style of for loop over the for-condition-increment style.

Preferred:
for _ in 0..<3 {
  println("Hello three times")
}
for person in attendeeList {
  // do something
}
Not Preferred:
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
}

14.分號(Semicolons)

Swift在任何語句后都不需要分號,分號僅在你將多個語句寫在一行時有用(用于區分語句)
Swift does not require a semicolon after each statement in your code. They are only required if you wish to combine multiple statements on a single line.
不要將多個語句寫在一行然后用分號區分
Do not write multiple statements on a single line separated with semicolons.
這個規則的唯一例外是for語句,它需要分號。然而,在可能的情況下盡量使用可選的 for-in 語句
The only exception to this rule is the for-conditional-increment construct, which requires semicolons. However, alternative for-in constructs should be used where possible.

Preferred:
var swift = "not a scripting language"
Not Preferred:
var swift = "not a scripting language";
注意:Swift與javascript非常不一樣,javascript認為省略分號是不安全的。

NOTE: Swift is very different to JavaScript, where omitting semicolons is generally considered unsafe

15.語言(Language)

與Apple API一樣使用US English 拼寫,盡量使用英語的拼寫方式。
Use US English spelling to match Apple's API.

Preferred:
var color = "red"
Not Preferred:
var colour = "red"
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容