中文字幕在线观看,亚洲а∨天堂久久精品9966,亚洲成a人片在线观看你懂的,亚洲av成人片无码网站,亚洲国产精品无码久久久五月天

Swift編程規(guī)范:保持代碼優(yōu)美的10個(gè)方法

2018-07-20    來(lái)源:編程學(xué)習(xí)網(wǎng)

容器云強(qiáng)勢(shì)上線!快速搭建集群,上萬(wàn)Linux鏡像隨意使用

  這篇Swift風(fēng)格指南與你看到的其他的指南有所不同,此篇指南主要焦點(diǎn)集中在打印和Web展示的可讀寫(xiě)上。我們創(chuàng)建此篇風(fēng)格指南的目的,是為了讓我們的圖書(shū)、教程以及初學(xué)者套件中的代碼保持優(yōu)美和一致,即使我們有很多不同的作者共同編寫(xiě)這些圖書(shū)。

  我們的首要目標(biāo)是一致性,可讀性和簡(jiǎn)潔性。

  還在使用Objective-C?也可以參考我們的Objective-C風(fēng)格指南(中譯版)。

 命名(Naming)

  使用駝峰式的描述性命名方式,為類(lèi),方法,變量等命名。類(lèi)名的首字母應(yīng)該大寫(xiě),而方法和變量的首字母使用小寫(xiě)字符。

  推薦做法:

private let maximumWidgetCount = 100
class WidgetContainer {
  var widgetButton: UIButton
  let widgetHeightPercentage = 0.85
}

  不推薦做法:

let MAX_WIDGET_COUNT = 100
class app_widgetContainer {
  var wBut: UIButton
  let wHeightPct = 0.85
}

  對(duì)于函數(shù)和初始化方法,推薦對(duì)所有的參數(shù)進(jìn)行有意義的命名,除非上下文已經(jīng)非常清楚。如果外部參數(shù)命名可以使得函數(shù)調(diào)用更加可讀,也應(yīng)該把外部參數(shù)命名包含在內(nèi)。

func dateFromString(dateString: String) -> NSDate
func convertPointAt(#column: Int, #row: Int) -> CGPoint
func timedAction(#delay: NSTimeInterval, perform action: SKAction) -> SKAction!
// 調(diào)用方式如下:
dateFromString("2014-03-14")
convertPointAt(column: 42, row: 13)
timedAction(delay: 1.0, perform: someOtherAction)

  對(duì)于方法來(lái)說(shuō),參照標(biāo)準(zhǔn)的蘋(píng)果慣例,方法命名含義要引用到第一個(gè)參數(shù):

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

 枚舉(Enumerations)

  使用首字母大寫(xiě)的駝峰命名規(guī)則來(lái)命名枚舉值:

enum Shape {
  case Rectangle
  case Square
  case Triangle
  case Circle
}

 文章(Prose)

  當(dāng)我們?cè)谖恼轮校ń坛,圖書(shū),注釋等)需要引用到函數(shù)時(shí),需要從調(diào)用者的視角考慮,包含必要的參數(shù)命名,或者使用_表示不需要命名的參數(shù)。

從你自身實(shí)現(xiàn)的init中調(diào)用convertPointAt(column:row:)。
如果你調(diào)用dateFromString(_:),需要保證你提供的輸入字符串格式是”yyyy-MM-dd”。
如果你需要在viewDidLoad()中調(diào)用timedAction(delay:perform:),記得提供調(diào)整后的延遲值和需要處理的動(dòng)作。
你不能直接調(diào)用數(shù)據(jù)源方法tableView(_:cellForRowAtIndexPath:)

  當(dāng)你遇到疑問(wèn)時(shí),可以看看Xcode在jump bar中是如何列出方法名的 —— 我們的風(fēng)格與此匹配。

 類(lèi)的前綴(Class Prefixes)

  Swift類(lèi)型自動(dòng)被模塊名設(shè)置了名稱空間,所以你不需要加一個(gè)類(lèi)的前綴。如果兩個(gè)來(lái)自不同模塊的命名沖突了,你可以附加一個(gè)模塊名到類(lèi)型命名的前面來(lái)消除沖突。

import SomeModule  

let myClass = MyModule.UsefulClass()

 空格(Spacing)

  • 使用2個(gè)空格的縮進(jìn)比使用tabs更好,可以減少占用空間和幫助防止多次換行。確保在Xcode進(jìn)行了下圖的偏好設(shè)置:

 

  • 方法定義的大括號(hào)或者其他大括號(hào)(if/else/switch/while等)—— 般都放在定義名稱的同一行,并且使用一個(gè)新的行來(lái)結(jié)束。
  • 提示:你可以通過(guò)以下方法重新進(jìn)行縮進(jìn):選擇一些代碼(或者使用?A選擇所有),然后按Control-I(或者點(diǎn)擊菜單欄 Editor\Structure\Re-Indent)。一些Xcode模板代碼使用的縮進(jìn)是4個(gè)空格,所以這種方法可以很好的修復(fù)縮進(jìn)。

  推薦做法:

if user.isHappy {
  // Do something
} else {
  // Do something else
}

  不推薦做法:

if user.isHappy
{
    // Do something
}
else {
    // Do something else
}
  • 應(yīng)該在方法之間空出一行,從視覺(jué)上有更好的區(qū)分和組織。方法內(nèi)的空白行隔開(kāi)不同的功能,但是當(dāng)一個(gè)方法中有很多段落時(shí),也意味著你應(yīng)該將該方法重構(gòu)成幾個(gè)方法。

 注釋(Comments)

  當(dāng)你需要時(shí),使用注釋來(lái)解釋一段特定的代碼段的作用。注釋必須保證更新或者及時(shí)刪除。

  避免在代碼中使用塊注釋,代碼盡可能自己能表達(dá)含義。以下情況除外:當(dāng)使用注釋來(lái)生成文檔時(shí)。

 類(lèi)和結(jié)構(gòu)體(Classes and Structures)

 選擇使用誰(shuí)?(Which one to use?)

  請(qǐng)記住,結(jié)構(gòu)體是值類(lèi)型。使用結(jié)構(gòu)體并沒(méi)有一個(gè)標(biāo)識(shí)。一個(gè)數(shù)組包含[a, b, c]和另外一個(gè)數(shù)組同樣包含[a, b, c]是完全一樣的,它們完全可以交換使用。使用第一個(gè)還是使用第二個(gè)無(wú)關(guān)緊要,因?yàn)樗鼈兇淼氖峭粋(gè)東西。這就是為什么數(shù)組是結(jié)構(gòu)體。

  類(lèi)是引用類(lèi)型。使用類(lèi)是有一個(gè)標(biāo)識(shí)或者有一個(gè)特定的生命周期。你需要對(duì)一個(gè)人類(lèi)建模為一個(gè)類(lèi),因?yàn)閮蓚(gè)不同的人的實(shí)例,是兩個(gè)不同的東西。只是因?yàn)閮蓚(gè)人有同樣的名字和生日,也不能斷定這兩個(gè)人是一樣的。但是人的生日是一個(gè)結(jié)構(gòu)體,因?yàn)槿掌?950-3-3和另外一個(gè)日期1950-3-3是相同的。日期不需要一個(gè)標(biāo)識(shí)。

  有時(shí),一些事物應(yīng)該定義為結(jié)構(gòu)體,但是需要兼容AnyObject或者已經(jīng)在以前的歷史版本中定義為類(lèi)(NSDate,NSSet)。盡可能的嘗試遵守這些規(guī)則。

 定義的案例(Example definition)

  以下是一個(gè)風(fēng)格很好的類(lèi)定義:

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

  以上例子遵循了以下風(fēng)格規(guī)范:

  • 指定屬性、變量、常量、參數(shù)定義或者其他定義的類(lèi)型,在冒號(hào)后面,緊跟著一個(gè)空格,而不是把空格放在冒號(hào)前面。比如:x: Int和Circle: Shape。
  • 如果能表示相同的目的和上下文,可以在同一行定義多個(gè)變量和結(jié)構(gòu)體。
  • 縮進(jìn)getter,setter的定義和屬性觀察器的定義。
  • 不需要添加internal這樣的默認(rèn)的修飾符。同樣的,不需要在重寫(xiě)一個(gè)方法時(shí)添加訪問(wèn)修飾符。

 Self的使用(Use of Self)

  為了保持簡(jiǎn)潔,避免使用 self 關(guān)鍵詞,Swift 不需要使用 self 來(lái)訪問(wèn)對(duì)象屬性和調(diào)用對(duì)象方法。

  必須使用 self 來(lái)區(qū)分構(gòu)造器中屬性命名和參數(shù)命名,還有在閉包表達(dá)式中引用屬性值(編譯器需要區(qū)分):

class BoardLocation {
  let row: Int, column: Int
  init(row: Int, column: Int) {
    self.row = row
    self.column = column
    let closure = {
      println(self.row)
    }
  }
}

 協(xié)議遵守(Protocol Conformance)

  當(dāng)我們對(duì)一個(gè)類(lèi)添加協(xié)議時(shí),推薦使用一個(gè)單獨(dú)的類(lèi)擴(kuò)展來(lái)實(shí)現(xiàn)協(xié)議的方法。這可以保持協(xié)議相關(guān)的方法聚合在一起,同時(shí)也可以簡(jiǎn)單的標(biāo)識(shí)出一個(gè)協(xié)議對(duì)應(yīng)類(lèi)中需要實(shí)現(xiàn)哪些對(duì)應(yīng)的方法。

  同時(shí),別忘了添加// MARK:,注釋可以使得代碼組織的更好!

  推薦做法:

class MyViewcontroller: UIViewController {
  // class stuff here
}
// MARK: - UITableViewDataSource
extension MyViewcontroller: UITableViewDataSource {
  // table view data source methods
}
// MARK: - UIScrollViewDelegate
extension MyViewcontroller: UIScrollViewDelegate {
 // scroll view delegate methods
}

  不推薦做法:

class MyViewcontroller: UIViewController, UITableViewDataSource, UIScrollViewDelegate {
  // all methods
}

 計(jì)算屬性(Computed Properties)

  為了保持簡(jiǎn)潔,如果一個(gè)計(jì)算屬性是只讀的,請(qǐng)忽略掉get語(yǔ)句。只有在需要定義set語(yǔ)句的時(shí)候,才提供get語(yǔ)句。

  推薦做法:

var diameter: Double {
  return radius * 2
}

  不推薦做法:

var diameter: Double {  
  get {  
    return radius * 2  
  }  
}  

 函數(shù)聲明(Function Declarations)

  保證短的函數(shù)定義在同一行中,并且包含左大括號(hào):

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

  在一個(gè)長(zhǎng)的函數(shù)定義時(shí),在適當(dāng)?shù)牡胤竭M(jìn)行換行,同時(shí)在下一行中添加一個(gè)額外的縮進(jìn):

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

 閉包表達(dá)式(Closure Expressions)

  如果閉包表達(dá)式參數(shù)在參數(shù)列表中的最后一個(gè)時(shí),使用尾部閉包表達(dá)式。給定閉包參數(shù)一個(gè)描述性的命名。

  推薦做法:

UIView.animateWithDuration(1.0) {
  self.myView.alpha = 0
}
UIView.animateWithDuration(1.0,
  animations: {
    self.myView.alpha = 0
  },
  completion: { finished in
    self.myView.removeFromSuperview()
  }
)

  不推薦做法:

UIView.animateWithDuration(1.0, animations: {
  self.myView.alpha = 0
})
UIView.animateWithDuration(1.0,
  animations: {
    self.myView.alpha = 0
  }) { f in
    self.myView.removeFromSuperview()
}

  當(dāng)單個(gè)閉包表達(dá)式上下文清晰時(shí),使用隱式的返回值:

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

 類(lèi)型(Types)

  盡可能使用 Swift 原生類(lèi)型。Swift 提供到 Objective-C 類(lèi)型的橋接,所以你仍然可以使用許多需要的方法。

  推薦做法:

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可以使得代碼更加簡(jiǎn)明,避免很多轉(zhuǎn)換。

 常量(Constants)

  常量定義使用 let 關(guān)鍵字,變量定義使用 var 關(guān)鍵字,如果變量的值不需要改變,請(qǐng)盡量使用 let 關(guān)鍵字。

  提示:一個(gè)好的技巧是,使用 let 定義任何東西,只有在編譯器告訴我們值需要改變的時(shí)候才改成 var 定義。

 可選類(lèi)型(Optionals)

  當(dāng)nil值是可以接受的時(shí)候時(shí),定義變量和函數(shù)返回值為可選類(lèi)型(?)。

  當(dāng)你確認(rèn)變量在使用前已經(jīng)被初始化時(shí),使用!來(lái)顯式的拆包類(lèi)型,比如在viewDidLoad中會(huì)初始化subviews。

  當(dāng)你訪問(wèn)一個(gè)可選值時(shí),如果只需要訪問(wèn)一次或者在可選值鏈中有多個(gè)可選值時(shí),請(qǐng)使用可選值鏈:

self.textContainer?.textLabel?.setNeedsDisplay()

  當(dāng)需要很方便的一次性拆包或者添加附加的操作時(shí),請(qǐng)使用可選值綁定:

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

  當(dāng)我們命名一個(gè)可選變量和屬性時(shí),避免使用諸如optionalString和maybeView這樣的命名,因?yàn)榭蛇x值的表達(dá)已經(jīng)在類(lèi)型定義中了。

  在可選值綁定中,直接映射原始的命名比使用諸如unwrappedView和actualLabel要好。

  推薦做法:

var subview: UIView?
var volume: Double?
// later on...
if let subview = subview, volume = volume {
  // do something with unwrapped subview and volume
}

  不推薦做法:

var optionalSubview: UIView?
var volume: Double?
if let unwrappedSubview = optionalSubview {
  if let realVolume = volume {
    // do something with unwrappedSubview and realVolume
  }
}

 結(jié)構(gòu)體構(gòu)造器(Struct Initializers)

  使用原生的 Swift 結(jié)構(gòu)體構(gòu)造器,比老式的幾何類(lèi)(CGGeometry)的構(gòu)造器要好。

  推薦做法:

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

  不推薦做法:

let bounds = CGRectMake(40, 20, 120, 80)
let centerPoint = CGPointMake(96, 42)

  推薦使用結(jié)構(gòu)體限定的常量CGRect.infiniteRect,CGRect.nullRect等,來(lái)替代全局常量CGRectInfinite,CGRectNull等。對(duì)于已經(jīng)存在的變量,可以直接簡(jiǎn)寫(xiě)成 .zeroRect。

 類(lèi)型推斷(Type Inference)

  推薦使用更加緊湊的代碼,讓編譯器能夠推斷出常量和變量的類(lèi)型。除非你需要定義一個(gè)特定的類(lèi)型(比如CGFloat和Int16),而不是默認(rèn)的類(lèi)型。

  推薦做法:

let message = "Click the button"
let currentBounds = computeViewBounds()
var names = [String]()
let maximumWidth: CGFloat = 106.5

  不推薦做法:

let message: String = "Click the button"
let currentBounds: CGRect = computeViewBounds()
var names: [String] = []

  注意:遵守這條規(guī)則意味選擇描述性命名比之前變得更加重要。

 語(yǔ)法糖(Syntactic Sugar)

  推薦使用類(lèi)型定義簡(jiǎn)潔的版本,而不是全稱通用語(yǔ)法。

  推薦做法:

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

  不推薦做法:

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

 控制流(Control Flow)

  推薦循環(huán)使用for-in表達(dá)式,而不使用for-condition-increment表達(dá)式。

  推薦做法:

for _ in 0..<3 {
  println("Hello three times")
}
for (index, person) in enumerate(attendeeList) {
  println("\(person) is at position #\(index)")
}

 不推薦做法:

for var i = 0; i < 3; i++ {  
  println("Hello three times")  
}  
for var i = 0; i < attendeeList.count; i++ {  
  let person = attendeeList[i]  
  println("\(person) is at position #\(i)")  
}  

 分號(hào)(Semicolons)

  Swift不需要在你代碼中的每一句表達(dá)式之后添加分號(hào)。只有在你需要在一行中連接多個(gè)表達(dá)式中,使用分號(hào)來(lái)區(qū)隔。

  不要在同一行編寫(xiě)多個(gè)使用分號(hào)區(qū)隔的表達(dá)式。

  唯一的例外是在使用for-conditional-increment 架構(gòu)。然而,盡可能使用for-in架構(gòu)來(lái)替代它。

  推薦做法:

let swift = "not a scripting language"

  不推薦做法: 

let swift = "not a scripting language";

  注意:Swift與JavaScript有很大的不同,JavaScript認(rèn)為忽略分號(hào)通常認(rèn)為是不安全的。

 語(yǔ)言(Language)

  使用美式英語(yǔ)拼音符合Apple API的標(biāo)準(zhǔn)。

  推薦做法:

let color = "red"

  不推薦做法:

let colour = "red"

 版權(quán)聲明(Copyright Statement)

  以下的版權(quán)聲明應(yīng)該被包含在所有源文件的頂部:

/*
 * Copyright (c) 2015 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.
 * 
 * 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.
 */

  笑臉(Smiley Face)

  笑臉是raywenderlich.com網(wǎng)站非常重要的風(fēng)格特性!擁有一個(gè)正確的笑臉,表達(dá)代碼文章中開(kāi)心和激動(dòng),是非常重要的。使用]來(lái)代表笑臉,因?yàn)檫@代表ASCII中最大的笑臉。)只能創(chuàng)建半個(gè)心型笑臉,所以不推薦使用。

  推薦做法:

:]

  不推薦做法:

:)

 作者(Credits)

  這篇風(fēng)格指南是所有raywenderlich.com團(tuán)隊(duì)成員共同的努力:

  • Jawwad Ahmad
  • Soheil Moayedi Azarpour
  • Scott Berrevoets
  • Eric Cerney
  • Sam Davies
  • Evan Dekhayser
  • Jean-Pierre Distler
  • Colin Eberhardt
  • Greg Heo
  • Matthijs Hollemans
  • Erik Kerber
  • Christopher LaPollo
  • Ben Morrow
  • Andy Pereira
  • Ryan Nystrom
  • Cesare Rocchi
  • Ellen Shapiro
  • Marin Todorov
  • Chris Wagner
  • Ray Wenderlich
  • Jack Wu

  向Nicholas Waynik和Objective-C Style Guide團(tuán)隊(duì)脫帽致敬。

  我們同時(shí)也從蘋(píng)果的官方Swift資料中尋找靈感:

  • The Swift Programming Language
  • Using Swift with Cocoa and Objective-C
  • Swift Standard Library Reference

  本文出自:The Official raywenderlich.com Swift Style Guide,譯文出自:SwiftGG

標(biāo)簽: isp 安全 代碼

版權(quán)申明:本站文章部分自網(wǎng)絡(luò),如有侵權(quán),請(qǐng)聯(lián)系:west999com@outlook.com
特別注意:本站所有轉(zhuǎn)載文章言論不代表本站觀點(diǎn)!
本站所提供的圖片等素材,版權(quán)歸原作者所有,如需使用,請(qǐng)與原作者聯(lián)系。

上一篇:10個(gè)實(shí)用的但偏執(zhí)的Java編程技術(shù)

下一篇:每個(gè)Android開(kāi)發(fā)者應(yīng)該知道的6個(gè)SDK和API