[转]Swift编程风格指南
语言
使用美式英语拼写以匹配苹果公司的API
- 优选:
- var color = "red"
- 不建议使用:
- 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类型暴露在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:有一个方法可以帮你符合该项规则,将所有值都定义成常量,然后编译器提示的时候将其改为变量。
Optionals
在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()
注意:遵循这条准则意味着描述性强的名称比之前更为重要了。
控制流
对于for
循环,优选for-in
风格而不是for-condition-increment
风格:
- 优选:
- for _ in 0..5 {
- println("Hello five times")
- }
- for person in attendeeList {
- // do something
- }
- 不建议使用:
- for var i = 0; i < 5; i++ {
- println("Hello five times")
- }
- for var i = 0; i < attendeeList.count; i++ {
- let person = attendeeList[i]
- // do something
- }
笑脸
笑脸对于raywenderlich.com来说是一个格外重要的风格特征。使用正确的笑脸可以表示出对某个主题的无穷尽的高兴以及兴奋程度。选用了]
是因为它在ASCII艺术可以表示得最大的笑脸。而闭圆括号)
因为给人一种“呵呵”的感觉而不建议使用。
优选:
:]
不建议使用:
:)
本文版权归 raywenderlich.com 、The Official raywenderlich.com Swift Style Guide项目以及所有贡献者所有。
译者翻译仅供知识传播使用。
本风格指南的目标是让Swift代码更简洁、可读更强。
[转]Swift编程风格指南的更多相关文章
- Swift 编程风格指南(raywenderlich.com 版本号)
官方 raywenderlich.com Swift 编程风格指南 本文版权归 raywenderlich.com .The Official raywenderlich.com Swift Styl ...
- raywenderlich.com的Swift编程风格指南
翻译自:https://github.com/raywenderlich/swift-style-guide 这个风格指南可能和你从其它地方看到的不同,我们的焦点主要集中在互联网和文章上的可读性.创建 ...
- Google Java编程风格指南
出处:http://hawstein.com/posts/google-java-style.html 声明:本文采用以下协议进行授权: 自由转载-非商用-非衍生-保持署名|Creative Comm ...
- Google Java编程风格指南中文版
作者:Hawstein出处:http://hawstein.com/posts/google-java-style.html声明:本文采用以下协议进行授权: 自由转载-非商用-非衍生-保持署名|Cre ...
- Java学习笔记(四)——google java编程风格指南(上)
[前面的话] 年后开始正式上班,计划着想做很多事情,但是总会有这样那样的打扰,不知道是自己要求太高还是自我的奋斗意识不够?接下来好好加油.好好学学技术,好好学习英语,好好学习做点自己喜欢的事情,趁着自 ...
- Java学习笔记(五)——google java编程风格指南(中)
[前面的话] 年后开始正式上班,计划着想做很多事情,但是总会有这样那样的打扰,不知道是自己要求太高还是自我的奋斗意识不够?接下来好好加油.好好学学技术,好好学习英语,好好学习做点自己喜欢的事情,趁着自 ...
- Java学习笔记(六)——google java编程风格指南(下)
[前面的话] 年后开始正式上班,计划着想做很多事情,但是总会有这样那样的打扰,不知道是自己要求太高还是自我的奋斗意识不够?接下来好好加油.好好学学技术,好好学习英语,好好学习做点自己喜欢的事情,趁着自 ...
- MATLAB 编程风格指南及注意事项
MATLAB编程风格指南Richard Johnson 著Genial 译MATLAB 编程风格指南Richard JohnsonVersion 1.5,Oct. 2002版权: Datatool 所 ...
- Google的Java编程风格指南(Java编码规范)
这份文档是Google Java编程风格规范的完整定义.当且仅当一个Java源文件符合此文档中的规则, 我们才认为它符合Google的Java编程风格. 与其它的编程风格指南一样,这里所讨论的不仅仅是 ...
随机推荐
- 实现DIV拖动
Ajax的到来让B/S中的客户端中开发有火了一把,网上出现了很多优秀的开源框架和UI,比较著名了有prototype,YUI,GWT等,但很多时候发现这些东西很难用到你的系统之中,有时候你的系统仅仅需 ...
- div边框阴影的实现【转载】
box-shadow:阴影水平偏移值(可取正负值): 阴影垂直偏移值(可取正负值):阴影模糊值:阴影颜色: Firefox支持Box Shadow(阴影):-moz-box-shadow:2px 2p ...
- PHP的抽象类和接口
抽象类与接口相似,都是一种比较特殊的类.抽象类是一种特殊的类,而接口也是一种特殊的抽象类.它们通常配合面向对象的多态性一起使用.虽然声明和使用都比较容易,但它们的作用在理解上会困难一点. ①抽象类 在 ...
- 性能测试工具--SIEGE安装及使用简介
官方网站http://www.joedog.org/ 概述 Siege是一个多线程http负载测试和基准测试工具.它有3种操作模式: 1) Regression (when invoked by bo ...
- [工具]前端自动化工具grunt+bower+yoman
安装过程 安装nodejs 安装grunt,bower,yoeman 命令:(-g 表示全局安装,否则安装到当前目录下) npm install -g grunt-cli npm install -g ...
- nmap svn
http://stackoverflow.com/questions/13296361/nmap-and-svnlib-client-not-working-together http://nmap. ...
- LeetCode _ Word Break
Given a string s and a dictionary of words dict, determine if s can be segmented into a space-separa ...
- 用TMS的控件就可以了,有bug叫他们改
[深圳]大宝delphi本身不是太隐定.不建议弄太多自己的东西.还要debug好长时间.为了快.便不去弄控件了够用了.真的.都不用花太多时间去弄这弄那.有bug叫他们改便可以.
- 理解 break, continue, return 和 exit
你们知道 “break”, “continue”, “return” 和 “exit”的作用吗? 它们是功能强大的语言结构体.下面通过一个测试函数来说明它们之间的不同. 1 2 3 4 5 6 7 8 ...
- 设计模式(十二): Flyweight享元模式 -- 结构型模式
说明: 相对于其它模式,Flyweight模式在PHP实现似乎没有太大的意义,因为PHP的生命周期就在一个请求,请求执行完了,php占用的资源都被释放.我们只是为了学习而简单做了介绍. 1. 概述 面 ...