Swift 編碼規範
Swift 編碼規範
按大概的先後順序,本文嘗試做到以下幾點:- 增進精確,減少程式設計師犯錯的可能
- 明確意圖
- 減少冗餘
- 減少關於美的爭論
pull request
. ⚡️留空白
- 用 tab,而非 空格
- 檔案結束時留一空行
- 用足夠的空行把程式碼分割成合理的塊
- 不要在一行結尾留下空白
- 千萬別在空行留下縮排
能用 let
儘量用 let
而不是 var
儘可能的用 let foo = ...
而不是 var foo = ...
(並且包括你疑惑的時候)。萬不得已的時候,再用 var
(就是說:你 知道 這個值會改變,比如:有 weak
修飾的儲存變數)。 理由: 這倆關鍵字 無論意圖還是意義 都很清楚了,但是 let
可以產生安全清晰的程式碼。let
保障它的值的永遠不會變,對程式猿也是個 清晰的標記。因此對於它的用法,之後的程式碼可以做個強而有力的推斷。 理解程式碼也更容易了。不然一旦你用了 var
,還要去推測值會不會變,這時候你就不得不人肉去檢查。 相應地,無論何時你看到 var
,就假設它會變,並問自己為啥。 儘早地 return
或者 break
當你遇到某些操作需要通過條件判斷去執行,應當儘早地退出判斷條件:你不應該用下面這種寫法if n.isNumber {
// Use n here
} else {
return
}
guard n.isNumber else {
return
}
// Use n here
if
宣告,但是我們推薦你使用 guard
理由: 你一但宣告 guard
編譯器會強制要求你和 return
, break
或者 continue
一起搭配使用,否則會產生一個編譯時的錯誤。避免對 可選型別 強解包
如果你有個FooType?
或 FooType!
的 foo
,儘量不要強行展開它(foo!
)以得到它的關聯值。取而代之的,推薦這樣:if let foo = foo {
// Use unwrapped `foo` value in here
} else {
// If appropriate, handle the case where the optional is nil
}
// Call the function if `foo` is not nil. If `foo` is nil, ignore we ever tried to make the call
foo?.callSomethingIfFooIsNotNil()
if let
繫結可選型別產生了更安全的程式碼,強行展開很可能導致執行時崩潰。避免隱式解析的可選型別
如果 foo 可能為nil
,儘可能的用 let foo: FooType?
代替 let foo: FooType!
(注意:一般情況下,?
可以代替 !
)理由: 明確的可選型別產生了更安全的程式碼。隱式解析的可選型別也可能會掛。對於只讀屬性和 subscript
,選用隱式的 getters 方法
如果可以,省略只讀屬性和 subscript
的 get
關鍵字所以應該這樣寫:var myGreatProperty: Int {
return 4
}
subscript(index: Int) -> T {
return objects[index]
}
var myGreatProperty: Int {
get {
return 4
}
}
subscript(index: Int) -> T {
get {
return objects[index]
}
}
對於頂級定義,永遠明確的列出許可權控制
頂級函式,型別和變數,永遠應該有著詳盡的許可權控制說明符public var whoopsGlobalState: Int
internal struct TheFez {}
private func doTheThings(things: [Thing]) {}
internal struct TheFez {
var owner: Person = Joshaber()
}
internal
很少有恰當的,要明確的確保經過了仔細的判斷。在定義的內部重用同樣的許可權控制說明符就顯得重複,而且預設的通常是合理的。當指定一個型別時,把 冒號和識別符號 連在一起
當指定標示符的型別時,冒號要緊跟著標示符,然後空一格再寫型別class SmallBatchSustainableFairtrade: Coffee { ... }
let timeToCoffee: NSTimeInterval = 2
func makeCoffee(type: CoffeeType) -> Coffee { ... }
此外,指定字典型別時,鍵型別後緊跟著冒號,接著加一個空格,之後才是值型別。
let capitals: [Country: City] = [sweden: stockholm]
需要時才寫上 self
當呼叫 self
的屬性或方法時,預設隱式引用self
:private class History {
var events: [Event]
func rewrite() {
events = []
}
}
self
, 比如在(逃逸)閉包裡,或者 引數名衝突了:extension History {
init(events: [Event]) {
self.events = events
}
var whenVictorious: () -> () {
return {
self.rewrite()
}
}
}
self
更加凸顯它捕獲 self
的語義,別處避免了冗長首選 struct
而非 class
除非你需要 class
才能提供的功能(比如 identity 或 deinit
ializers),不然就用 struct
要注意到繼承通常 不 是用 類 的好理由,因為 多型 可以通過 協議 實現,重用 可以通過 組合 實現。比如,這個類的分級class Vehicle {
let numberOfWheels: Int
init(numberOfWheels: Int) {
self.numberOfWheels = numberOfWheels
}
func maximumTotalTirePressure(pressurePerWheel: Float) -> Float {
return pressurePerWheel * Float(numberOfWheels)
}
}
class Bicycle: Vehicle {
init() {
super.init(numberOfWheels: 2)
}
}
class Car: Vehicle {
init() {
super.init(numberOfWheels: 4)
}
}
protocol Vehicle {
var numberOfWheels: Int { get }
}
func maximumTotalTirePressure(vehicle: Vehicle, pressurePerWheel: Float) -> Float {
return pressurePerWheel * Float(vehicle.numberOfWheels)
}
struct Bicycle: Vehicle {
let numberOfWheels = 2
}
struct Car: Vehicle {
let numberOfWheels = 4
}
let
關鍵字的行為符合預期。預設 class
為 final
class
應該用 final
修飾,並且只有在繼承的有效需求已被確定時候才能去使用子類。即便在這種情況(前面提到的使用繼承的情況)下,根據同樣的規則(class
應該用 final
修飾的規則),類中的定義(屬性和方法等)也要儘可能的用 final
來修飾理由: 組合通常比繼承更合適,選擇使用繼承則很可能意味著在做出決定時需要更多的思考。能不寫型別引數的就別寫了
當對接收者來說一樣時,引數化型別的方法可以省略接收者的型別引數。比如:struct Composite<T> {
…
func compose(other: Composite<T>) -> Composite<T> {
return Composite<T>(self, other)
}
}
struct Composite<T> {
…
func compose(other: Composite) -> Composite {
return Composite(self, other)
}
}
定義操作符 兩邊留空格
當定義操作符時,兩邊留空格。不要醬紫:func <|(lhs: Int, rhs: Int) -> Int
func <|<<A>(lhs: A, rhs: A) -> A
func <| (lhs: Int, rhs: Int) -> Int
func <|< <A>(lhs: A, rhs: A) -> A
相關文章
- 程式碼規範之前端編寫碼規範前端
- html編碼規範HTML
- Pear 編碼規範
- CSS編碼規範CSS
- Javascript編碼規範JavaScript
- python編碼規範Python
- stylus編碼規範
- 常見編碼規範
- 前端安全編碼規範前端
- .Net編碼規範整理
- WEB前端編碼規範Web前端
- .Net Core 編碼規範
- PHP編碼風格規範PHP
- Java語言編碼規範Java
- HTML編碼規範建議HTML
- 前端開發編碼規範前端
- Uber Go 語言編碼規範Go
- 編寫shell指令碼的規範指令碼
- 前端設計與編碼規範前端
- PHP – 編碼規範 v1.0PHP
- Python基礎:編碼規範(4)Python
- 前端單體編碼規範整理前端
- 編碼規範 - 養成良好的Java編碼習慣Java
- 上位機程式設計編碼規範程式設計
- Kitty-Cloud中的編碼規範Cloud
- 談談編碼風格與規範
- 我的編碼習慣 —— Controller規範Controller
- ReactNative專案實踐編碼規範React
- python編碼規範以及推導式的編寫Python
- 嵌入式c語言編碼規範C語言
- 阿里巴巴編碼規範(Java)證明阿里Java
- Java語言編碼規範(Java Code Conventions)Java
- HTML編寫規範HTML
- PHP 規範 - Symfony 程式碼規範PHP
- Java的識別符號與編碼規範Java符號
- 『手撕Vue-CLI』編碼規範檢查Vue
- 編碼規範 | Java函式優雅之道(下)Java函式
- 編碼規範 | Java函式優雅之道(上)Java函式
- Google 的 Java 編碼規範,參考學習!GoJava