这是一份raywenderlich的Swift编程风格指南,中文版由@mrahmiao翻译,你能够前往Github访问这个项目。 javascript
由于该指南关注于网页上以及打印版的可读性,因此它可能与你阅读过的指南有所不一样。为了保证那些在咱们书中、教程里以及初学者工程里的代码美观而且一致,咱们写下了这份风格指南,尽管书由许多不一样做者共同创做而成。 java
该指南的首要目标是让代码紧凑,可读性高且简洁。 node
正在用Objective-C写程序?也看看咱们的Objective-C风格指南吧。 git
语言 github
使用美式英语拼写以确保和苹果公司的API一致。 objective-c
优选: 编程
var color = "red"
不建议使用: swift
var colour = "red"
间隔 安全
使用2个空格而不是Tab进行缩进,能够减小换行。确保在Xcode的配置项中使用此设置。 闭包
方法的花括号以及其它花括号(if/else/switch/while等等)老是跟语句在同一行开始,新起一行结束。
优选:
if user.isHappy { //Do something } else { //Do something else }
不建议使用:
if user.isHappy { //Do something } else { //Do something else }
方法之间应该老是用一个空行进行分隔以提升视觉以及结构上的清晰度。方法中的空白用来分开功能块,可是若是一个方法中存在太多功能块时,一般意味着你须要将它重构为多个方法。
注释
在须要的时候使用注释说明一块代码为何这么作。注释必须时刻跟进代码,否则不如不要。
代码应该尽量的自文档化,避免在代码中使用成块的注释。例外:该规则不适用与用于生成文档的块注释。
命名
使用驼峰法为类、方法、变量等取一个描述性强的名字。模块范围的类名和常量名以大写字母开头,而方法名和变量名应以小写字母开头。
优选:
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 }
对于函数以及初始化方法,除非上下文含义很是清楚,推荐对全部的参数都加以命名。若是外部参数名称可使得函数调用更易读,请加上它。
func dateFromString(dateString: NSString) -> NSDate func convertPointAt(#column: Int, #row: Int) -> CGPoint func timedAction(#delay: NSTimeInterval, perform action: SKAction) -> SKAction! // 会被这样调用 dateFromString("2014-03-14") convertPointAt(column: 42, row: 13) timedAction(delay: 1.0, perform: someOtherAction)
对于方法,遵循苹果公司的命名规范,在方法名中说起第一个参数:
class Guideline { func combineWithString(incoming: String, options: Dictionary?) { ... } func upvoteBy(amount: Int) { ... } }
在全部说起到函数的内容中(包括教程,书以及评论),请从调用者的视角进行考虑,将全部的必要参数名都包含进来:
dateFromString()函数真是太棒了。 在你的init()方法中调用convertPointAt(column:, row:)。 timedAction(delay:, perform:)的返回值可能为nil。 Guideline对象只有两个方法:combineWithString(options:)和upvoteBy()。 你不该该直接调用数据源方法tableView(cellForRowAtIndexPath:)。
类前缀
Swift中的类型会被自动加入包含它们的模块的命名空间。因此减小命名冲突的前缀已经没必要要了。若是同模块的两个名称冲突了,能够在名称前加上模块名消除歧义:
import MyModule var myClass = MyModule.MyClass()
不该该给本身建立的Swift类型加前缀。
若是须要把Swift类型暴露给Objective-C使用,你能够添加一个合适的前缀(前缀的命名请参考Objective-C风格指南):
@objc (RWTChicken) class Chicken { ... }
分号
Swift不要求每条语句后加分号。只有在你想把多条语句写到一行时才须要加上分号。
请不要在一行中写上用分号隔开的多条语句。
这条规则的惟一例外就是for-conditional-increment结构,该结构中分号是必需的。不过请尽可能用for-in结构代替它们。
优选:
var swift = "not a scripting language"
不建议使用:
var swift = "not a scripting language";
请注意:Swift与JavaScript不一样, 在后者中省略分号一般是不安全的。
类与结构体
下面是一个风格良好的类定义代码例子,请参考:
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 (\(x),\(y)) with an area of \(computeArea())" } func computeArea() -> Double { return M_PI * radius * radius } }
上面的例子阐述了以下的风格准则:
· 给属性、变量、常量、参数及其它语句指定类型时,在冒号的后面加上空格而不是前面,好比:x: Int跟Circle: Shape。
· 对getter跟setter定义以及属性观察器进行缩进。
· 若是多个变量、结构有着一样的目的或者上下文,在同一行上进行定义。
Self的使用
在Swift中访问对象属性或调用方法时不须要使用self,请避免使用它。
使用self的惟一理由是在初始化一个类或结构体时区分属性名和参数名:
class BoardLocation { let row: Int, column: Int init(row: Int,column: Int) { self.row = row self.column = column } }
函数声明
保持函数声明短小精悍,保持在一行内,花括号在同一行内开始:
func reticulateSplines(spline: [Double]) -> Bool { // reticulate code goes here }
对于有着长签名的函数,请在适当的位置进行断行且对后续行缩进一级:
func reticulateSplines(spline: [Double], adjustmentFactor: Double, translateConstant: Int, comment: String) -> Bool { // reticulate code goes here }
闭包
尽量地使用尾闭包语法。在全部的状况下给闭包参数一个描述性强的名称:
return SKAction.customActionWithDuration(effect.duration) { node, elapsedTime in // more code goes here }
对于上下文清晰的单表达式闭包,使用隐式的返回值:
attendeeList.sort { a, b in a > b }
类型
若是可能,使用Swift的原生类型。Swift提供了对Objective-C的桥接,若是须要,仍然可使用所有的Objective-C方法:
优选:
let width = 120.0 //Double let widthString = width.bridgeToObjectiveC().stringValue //String
不建议使用:
let width: NSNumber = 120.0 //NSNumber let widthString: NSString = width.stringValue //NSString
在Sprite Kit的代码中,若是CGFloat能够避免过多的转换从而使得代码简洁,那么请使用它。
常量
常量经过let关键字定义,而变量使用var关键字定义。任何值若是是一个不变量,那么请使用let关键字恰如其分地定义它。最后你会发现本身喜欢使用let远多于far。
Tip:有一个方法能够帮你知足该项规则,将全部值都定义成常量,而后编译器提示的时候将其改成变量。
Optional
在nil值可能出现的状况下,将变量跟函数返回值的类型经过?定义成Optional。
只有在肯定实例变量会在初始化以后才被使用的状况下,经过!将其定义为隐式解包类型(Implicitly Unwrapped Types),好比说会在viewDidLoad中被建立的子视图。
在访问一个Optional值时,若是该值只被访问一次,或者以后须要连续访问多个Optional值,请使用链式Optional语法:
myOptional?.anotherOne?.optionalView?.setNeedsDisplay()
对于须要将Optional值解开一次,而后进行多个操做的状况,使用Optional绑定更为方便:
if let view = self.optionalView { // do many things with view }
类型推导
Swift的编译器能够推导出变量和常量的类型。能够显式地提供类型别名(冒号后面声明的类型),不过大多数状况下这都是没必要要的。
保持代码紧凑,而后让编译器推断变量跟常量的类型。
优选:
let message = "Click the button" var currentBounds = computeViewBounds()
不建议使用:
let message: String = "Click the button" var currentBounds: CGRect = computeViewBounds()
注意:遵循这条准则意味着使用描述性强的名称比以前更为重要了。
语法糖
Prefer the shortcut versions of type declarations over the full generics syntax.
使用简写的类型声明,而不是它的全泛型版本。
优选:
var deviceModels: [String] var employees: [Int: String] var faxNumber: Int?
不建议使用:
var deviceModels: Array var employees: Dictionary var faxNumber: Optional
控制流
对于for循环,优选for-in风格而不是for-condition-increment风格:
优选:
for _ in 0..<3 { println("Hello three times") } for person in attendeeList { // do something }
不建议使用:
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 }
笑脸
笑脸对于raywenderlich.com来讲是一个格外重要的风格特征。使用正确的笑脸能够表示出对某个主题的无穷尽的高兴以及兴奋程度。选用了]是由于它在ASCII艺术能够表示得最大的笑脸。而闭圆括号)由于给人一种“呵呵”的感受而不建议使用。
优选:
:]
不建议使用:
:)