Swift編碼風(fēng)格指南

swift

最近在閱讀swift進(jìn)階這本書,其中的風(fēng)格指南,我每次打開書要讀的時(shí)候,我都會(huì)先看一遍這個(gè)指南,因?yàn)橛X得真的很好.這里貼在簡(jiǎn)書上,和大家分享一下,有些指南后面我會(huì)加上示例代碼:

對(duì)于命名媒咳,在使用時(shí)能清晰表意是最重要。因?yàn)?API 被使用的次數(shù)要遠(yuǎn)遠(yuǎn)多于被聲明的次數(shù)翎朱,所以我們應(yīng)當(dāng)從使用者的角度來考慮它們的名字婴梧。盡快熟悉 Swift API 設(shè)計(jì)準(zhǔn)則枪汪,并且在你自己的代碼中堅(jiān)持使用這些準(zhǔn)則

// 盡量讓命名語義化,而且swift不需要前綴,因?yàn)橛忻臻g

// GOOD
extension List {
  public mutating func remove(at position: Index) -> Element
}
employees.remove(at: x)

// 反例

// BAD
extension List {
  public mutating func removeAt(position: Index) -> Element
}
employees.remove(x)

簡(jiǎn)潔經(jīng)常有助于代碼清晰藕筋,但是簡(jiǎn)潔本身不應(yīng)該獨(dú)自成為我們編碼的目標(biāo)

務(wù)必為函數(shù)添加文檔注釋 — 特別是泛型函數(shù)

    // 官方的API里面map函數(shù)的注釋文檔,記住如果你想讓你的注釋
    // 像官方文檔一樣按住option單擊左鍵就能看到,請(qǐng)使用 /// 
    
    // GOOD
    /// Returns an array containing the results of mapping the given closure
    /// over the sequence's elements.
    ///
    /// In this example, `map` is used first to convert the names in the array
    /// to lowercase strings and then to count their characters.
    ///
    ///     let cast = ["Vivien", "Marlon", "Kim", "Karl"]
    ///     let lowercaseNames = cast.map { $0.lowercaseString }
    ///     // 'lowercaseNames' == ["vivien", "marlon", "kim", "karl"]
    ///     let letterCounts = cast.map { $0.characters.count }
    ///     // 'letterCounts' == [6, 6, 3, 4]
    ///
    /// - Parameter transform: A mapping closure. `transform` accepts an
    ///   element of this sequence as its parameter and returns a transformed
    ///   value of the same or of a different type.
    /// - Returns: An array containing the transformed elements of this
    ///   sequence.
    public func map<T>(_ transform: (Element) throws -> T) rethrows -> [T]
    
    // 反例,下面這種注釋是很多人會(huì)范的錯(cuò)
    // 更值得提示的是,請(qǐng)多使用MARK來給業(yè)務(wù)邏輯分段
    
    // BAD
    // map函數(shù)
    public func map<T>(_ transform: (Element) throws -> T) rethrows -> [T]

類型使用大寫字母開頭,函數(shù)竭鞍、變量和枚舉成員使用小寫字母開頭匣椰,兩者都使用駝峰式命名法

// Class使用大寫字母開頭就不用多說了.
// 這里需要注意的是,在swift中,enum使用小寫字母開頭
// 這個(gè)跟OC有很大區(qū)別

// GOOD
enum RequestPath {
    case index
    case discover
}

// BAD
enum RequestPath {
    case Index
    case Discover
}

使用類型推斷裆熙。省略掉顯而易見的類型會(huì)有助于提高可讀性

// 有人覺得使用類型推斷會(huì)使得執(zhí)行效率下降
// 筆者可以負(fù)責(zé)任的告訴你,完全不會(huì),因?yàn)轭愋屯茢嗍蔷幾g器完成的

// GOOD
let str: String = "ABC"

// BAD
let str = "ABC"

優(yōu)先選擇結(jié)構(gòu)體,只在確實(shí)需要使用到類特有的特性或者是引用語義時(shí)才使用類

swiftstruct是值類型(value type),而類是引用類型(reference type),值類型在傳遞的過程中是會(huì)被拷貝的,所以無副作用

除非你的設(shè)計(jì)就是希望某個(gè)類被繼承使用,否則都應(yīng)該將它們標(biāo)記為 final

swift中被標(biāo)記final關(guān)鍵字的類,都是不允許繼承的,如果是方法被標(biāo)記了final,則是不允許重寫

除非一個(gè)閉包后面立即跟隨有左括號(hào)入录,否則都應(yīng)該使用尾隨閉包 (trailing closure) 的語法

// GOOD       
UIView.animate(withDuration: 0.3) {
            
}

// BAD
UIView.animate(withDuration: 0.3, animations: {
            
})

使用 guard 來提早退出方法

// guard可以使得條件不成立的時(shí)候執(zhí)行else里面的代碼
// 如果成立則繼續(xù)執(zhí)行下面的代碼

// GOOD
guard webView.isKind(of: WKWebView.self) else {
  return
}
// 執(zhí)行業(yè)務(wù)代碼

// BAD
if webView.isKind(of: WKWebView.self) {
  // 執(zhí)行業(yè)務(wù)代碼          
} else {
            
}

避免對(duì)可選值進(jìn)行強(qiáng)制解包和隱式強(qiáng)制解包耘分。它們偶爾有用惕味,但是經(jīng)常需要使用它們的話往往意味著有其他不妥的地方

這里沒啥可說的,誰用誰知道,結(jié)果就是crash,所以建議使用optional chains

self.textContainer?.textLabel?.setNeedsDisplay() // 保平安

不要寫重復(fù)的代碼霜第。如果你發(fā)現(xiàn)你寫了好幾次類似的代碼片段的話丐怯,試著將它們提取到一個(gè)函數(shù)里,并且考慮將這個(gè)函數(shù)轉(zhuǎn)化為協(xié)議擴(kuò)展的可能性

試著去使用 map 和 reduce蚀同,但這不是強(qiáng)制的缅刽。當(dāng)合適的時(shí)候,使用 for 循環(huán)也無可厚非蠢络。高階函數(shù)的意義是讓代碼可讀性更高衰猛。但是如果使用 reduce 的場(chǎng)景難以理解的話,強(qiáng)行使用往往事與愿違刹孔,這種時(shí)候簡(jiǎn)單的 for 循環(huán)可能會(huì)更清晰

// map
numbers.map { $0 * 2 }

// for
for i in numbers {
  i * 2
}

試著去使用不可變值:除非你需要改變某個(gè)值啡省,否則都應(yīng)該使用 let 來聲明變量。不過如果能讓代碼更加清晰高效的話髓霞,也可以選擇使用可變的版本卦睹。用函數(shù)將可變的部分封裝起來,可以把它帶來的副作用進(jìn)行隔離

除非你確實(shí)需要方库,否則不要使用 self.结序。在閉包表達(dá)式中,使用 self 是一個(gè)清晰的信號(hào)薪捍,表明閉包將會(huì)捕獲 self

// 有些開發(fā)者是從Objective - C轉(zhuǎn)過來的,非常喜歡使用self
// 其實(shí)在swift中完全沒有必要
// 但是在閉包中使用self是規(guī)定

anotherNum.map { num in
  self.numbers.append(num)
}

盡可能地對(duì)現(xiàn)有的類型和協(xié)議進(jìn)行擴(kuò)展笼痹,而不是寫一些全局函數(shù)配喳。這有助于提高可讀性酪穿,讓別人更容易發(fā)現(xiàn)你的代碼

// 多用extension
// 在開發(fā)中經(jīng)常遇到這樣的問題
// 如果把代理方法直接放在當(dāng)前類里面會(huì)使得代碼臃腫不堪
// 通過extension可以使得兩者分離開
// 如果你愿意,你甚至可以寫在兩個(gè)文件里面都沒有關(guān)系
// 比如代理方法,完全可以通過extension的方式使用
// 這樣是得代碼的調(diào)理性更加清晰

extension WebViewController: WKUIDelegate, WKNavigationDelegate {
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        self.title = webView.title!
    }
}

生命不息,折騰不止...
I'm not a real coder, but i love it so much!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末晴裹,一起剝皮案震驚了整個(gè)濱河市被济,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌涧团,老刑警劉巖只磷,帶你破解...
    沈念sama閱讀 219,039評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異泌绣,居然都是意外死亡钮追,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門阿迈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來元媚,“玉大人,你說我怎么就攤上這事】兀” “怎么了炭晒?”我有些...
    開封第一講書人閱讀 165,417評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長甥角。 經(jīng)常有香客問我网严,道長,這世上最難降的妖魔是什么嗤无? 我笑而不...
    開封第一講書人閱讀 58,868評(píng)論 1 295
  • 正文 為了忘掉前任震束,我火速辦了婚禮,結(jié)果婚禮上当犯,老公的妹妹穿的比我還像新娘驴一。我一直安慰自己,他們只是感情好灶壶,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評(píng)論 6 392
  • 文/花漫 我一把揭開白布肝断。 她就那樣靜靜地躺著,像睡著了一般驰凛。 火紅的嫁衣襯著肌膚如雪胸懈。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,692評(píng)論 1 305
  • 那天恰响,我揣著相機(jī)與錄音趣钱,去河邊找鬼。 笑死胚宦,一個(gè)胖子當(dāng)著我的面吹牛首有,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播枢劝,決...
    沈念sama閱讀 40,416評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼井联,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了您旁?” 一聲冷哼從身側(cè)響起烙常,我...
    開封第一講書人閱讀 39,326評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎鹤盒,沒想到半個(gè)月后蚕脏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,782評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡侦锯,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評(píng)論 3 337
  • 正文 我和宋清朗相戀三年驼鞭,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片尺碰。...
    茶點(diǎn)故事閱讀 40,102評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡挣棕,死狀恐怖汇竭,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情穴张,我是刑警寧澤细燎,帶...
    沈念sama閱讀 35,790評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站皂甘,受9級(jí)特大地震影響玻驻,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜偿枕,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評(píng)論 3 331
  • 文/蒙蒙 一璧瞬、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧渐夸,春花似錦嗤锉、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至苫幢,卻和暖如春访诱,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背韩肝。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評(píng)論 1 272
  • 我被黑心中介騙來泰國打工触菜, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人哀峻。 一個(gè)月前我還...
    沈念sama閱讀 48,332評(píng)論 3 373
  • 正文 我出身青樓涡相,卻偏偏與公主長得像,于是被迫代替她去往敵國和親剩蟀。 傳聞我的和親對(duì)象是個(gè)殘疾皇子催蝗,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容