官方 raywenderlich.com Swift 编程风格指南

本文版权归 raywenderlich.com 、The Official raywenderlich.com Swift Style Guide项目以及全部贡献者全部。

译者翻译仅供知识传播使用。

本风格指南的目标是让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
}

对于函数和构造器(init),除非能一目了然。否则建议为每一个參数命名。

假设能让函数可读性更强。请提供每一个參数的外部參数名。

func dateFromString(dateString: NSString) -> NSDate
func convertPointAt(#column: Int, #row: Int) -> CGPoint
func timedAction(#delay: NSTimeInterval, perform action: SKAction) -> SKAction! // would be called like this:
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) { ... }
}

假设在非代码文本(包括教程、书籍以及凝视中)中引用了某个函数。请提供函数全部參数的外部參数名:

The dateFromString() function is great.
Call convertPointAt(column:, row:) from your init() method.
The return value of timedAction(delay:, perform:) may be nil.
Guideline objects only have two methods: combineWithString(options:) and upvoteBy()
You shouldn't call the data source method tableView(cellForRowAtIndexPath:) directly.

类前缀

Swift中的模块(module)包括了命名空间。全部在模块中定义的类型名都不会与其他模块冲突。所以我们不再须要使用前缀命名来降低命名冲突。假设两个来自不同模块的同样名字须要同一时候引用。你能够使用模块名+点+类型名的方式来处理:

import MyModule

var myClass = MyModule.MyClass()

再次重申,请不要在Swift类型命名时加前缀。

假设你须要将Swift类型暴露给Objective-C,你能够为其指定一个在Objective-C中使用的合适前缀(请參考ObjC编程风格指南

@objc (RWTChicken) class Chicken {
...
}

分号

Swift不须要在每条语句后加分号。但假设将多条语句写在一行代码中,这时须要加上分号。

然而我们并不推荐这样的将多行语句写在一行的做法。 唯一例外是for-conditional-increment结构,它必须使用分号。但你应该尽量使用for-in结构来替代这样的行为: 推荐:

var swift = "not a scripting language"

不推荐:

var swift = "not a scripting language";

注意: Swift跟Javascript有很大差别,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
  • 属性的gettersetter以及属性观察器willSetdidSet的实现都须要缩进;
  • 假设多个变量和结构体有同样的使用目的或使用环境,能够将它们定义在同一行代码中。

Self 的使用

请避免在Swift中使用self,由于我们不须要使用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
}

闭包

请尽量使用掉尾(就是将最后一个闭包參数直接附在方法调用后,看起来像是控制语句的body一样)闭包语法。不管何时,请给闭包中每一个參数一个描写叙述性的名字:

return SKAction.customActionWithDuration(effect.duration) { node, elapsedTime in
// more code goes here
}

笔者:@aemaeth 提出将闭包參数另起一行的写法,我觉得更合理,攻克了多个闭包參数过长的问题。

对于一行表达式闭包,当使用场景明白时。能够使用隐式返回:

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

类型

请尽量使用Swift提供的原生类型。

Swift也提供了原生类型对象桥接到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,这样代码会更简洁,也能避免许多的类型转换。

常量

常量使用letkeyword定义,而变量使用varkeyword定义。

假设一个值是常量。那就必须使用letkeyword来准确定义。

终于你会发现。你使用let的频率远大于var

小技巧:一開始你能够将全部值都定义为常量,然后假设编译器报错了再作适当的调整。

可选

假设能够接受nil值。请将变量或函数返回值的类型定义为可选类型(加?)。

当你明白知道实例变量在使用前会完毕初始化,比方说视图控制器中的子视图subviews在使用前会在viewDidLoad中初始化,那么你能够将这些变量定义为隐式解析类型(使用!)。

当訪问一个可选值时。假设仅仅訪问一次,或者方式时有多种可能性,请使用可选链:

myOptional?.anotherOne?

.optionalView?.setNeedsDisplay()

使用可选绑定optional binding对仅仅拆包(unwrap)一次,但运行多次操作的情况很合适:

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-in风格的for循环,而不是传统的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艺术字符中最大的微笑。而使用右小括号)的笑脸显得有点不那么诚心,所以我们不推荐使用。

推荐:

:]

不推荐:

:)

Swift 编程风格指南(raywenderlich.com 版本号)的更多相关文章

  1. raywenderlich.com的Swift编程风格指南

    翻译自:https://github.com/raywenderlich/swift-style-guide 这个风格指南可能和你从其它地方看到的不同,我们的焦点主要集中在互联网和文章上的可读性.创建 ...

  2. [转]Swift编程风格指南

    语言 使用美式英语拼写以匹配苹果公司的API 优选: var color = "red" 不建议使用: var colour = "red" 间隔 使用2个空格 ...

  3. Google Java编程风格指南

    出处:http://hawstein.com/posts/google-java-style.html 声明:本文采用以下协议进行授权: 自由转载-非商用-非衍生-保持署名|Creative Comm ...

  4. Google Java编程风格指南中文版

    作者:Hawstein出处:http://hawstein.com/posts/google-java-style.html声明:本文采用以下协议进行授权: 自由转载-非商用-非衍生-保持署名|Cre ...

  5. Java学习笔记(四)——google java编程风格指南(上)

    [前面的话] 年后开始正式上班,计划着想做很多事情,但是总会有这样那样的打扰,不知道是自己要求太高还是自我的奋斗意识不够?接下来好好加油.好好学学技术,好好学习英语,好好学习做点自己喜欢的事情,趁着自 ...

  6. Java学习笔记(五)——google java编程风格指南(中)

    [前面的话] 年后开始正式上班,计划着想做很多事情,但是总会有这样那样的打扰,不知道是自己要求太高还是自我的奋斗意识不够?接下来好好加油.好好学学技术,好好学习英语,好好学习做点自己喜欢的事情,趁着自 ...

  7. Java学习笔记(六)——google java编程风格指南(下)

    [前面的话] 年后开始正式上班,计划着想做很多事情,但是总会有这样那样的打扰,不知道是自己要求太高还是自我的奋斗意识不够?接下来好好加油.好好学学技术,好好学习英语,好好学习做点自己喜欢的事情,趁着自 ...

  8. MATLAB 编程风格指南及注意事项

    MATLAB编程风格指南Richard Johnson 著Genial 译MATLAB 编程风格指南Richard JohnsonVersion 1.5,Oct. 2002版权: Datatool 所 ...

  9. Google的Java编程风格指南(Java编码规范)

    这份文档是Google Java编程风格规范的完整定义.当且仅当一个Java源文件符合此文档中的规则, 我们才认为它符合Google的Java编程风格. 与其它的编程风格指南一样,这里所讨论的不仅仅是 ...

随机推荐

  1. 【LeetCode】9 & 234 & 206 - Palindrome Number & Palindrome Linked List & Reverse Linked List

    9 - Palindrome Number Determine whether an integer is a palindrome. Do this without extra space. Som ...

  2. MATLAB Coder从MATLAB生成C/C++代码步骤

    MATLAB Coder可以从MATLAB代码生成独立的.可读性强.可移植的C/C++代码. 使用MATLAB Coder产生代码的3个步骤: 准备用于产生代码的MATLAB算法: 检查MATLAB代 ...

  3. AudioPolicyManager::setDeviceConnectionState 流程(一)

    当有线耳机插入/拔出或蓝牙耳机的插入/拔出等,这些事件都会引起Audio Route的重新配置.重新配置的过程实在AudioPolicyManager::setDeviceConnectionStat ...

  4. LeetCode(5) - Longest Palindromic Substring

    这道题要求的是给你一个string, 如“adcdabcdcba",要求返回长度最大的回文子字符串.这里有两个条件,一是子字符串,而是回文.用纯暴力搜索的话,需要用到O(n^3)的时间,必然 ...

  5. 多台服务器最好加上相同的machineKey

      <machineKey validationKey="6E993A81CF4BDCA1C1031528F55DADBB8AF1772A" decryptionKey=&q ...

  6. HDU 1787 GCD Again(欧拉函数,水题)

    GCD Again Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  7. 使用paramiko来实现sftp

    sftp是一个基于ssh的文件传输协议,是在Windows上往linux传送文件最常用的方式(例如SecureFX,Xftp). 在python下,paramiko实现了sftp,可以让大家方便地在代 ...

  8. POJ3345

    http://poj.org/problem?id=3345 大意: 大意是说现在有n个城市来给你投票,你需要至少拿到m个城市的赞成票.想要获得第i个城市的赞成需要花费w[i],有个条件就是某些城市是 ...

  9. CString的GetBuffer用法,GetBuffer本质,GetBuffer常见问题解决方法

    一.函数原型 CString::GetBuffer LPTSTR GetBuffer( int nMinBufLength ); throw( CMemoryException ); Return V ...

  10. 移动端类似IOS的滚动年月控件(需要jQuery和iScroll)

    一. 效果图 二. 功能介绍 支持滚动和点击选择年月.(目前只支持设置年月的最大最小值,不支持整体的最大最小值) 三. 代码 1. 在你的html中添加如下代码: 直接加载<body>里面 ...