文档章节

Swift 编程风格指南

法斗斗
 法斗斗
发布于 2016/03/01 18:52
字数 2231
阅读 58
收藏 1

这是一份raywenderlich的Swift编程风格指南,中文版由@mrahmiao翻译,你可以前往Github访问这个项目。

因为该指南关注于网页上以及打印版的可读性,所以它可能与你阅读过的指南有所不同。为了保证那些在我们书中、教程里以及初学者工程里的代码美观并且一致,我们写下了这份风格指南,尽管书由许多不同作者共同创作而成。

该指南的首要目标是让代码紧凑,可读性高且简洁。

正在用Objective-C写程序?也看看我们的Objective-C风格指南吧。

语言

使用美式英语拼写以确保和苹果公司的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类型加前缀。

如果需要把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艺术可以表示得最大的笑脸。而闭圆括号)因为给人一种“呵呵”的感觉而不建议使用。

优选:

:]

不建议使用:

:)

本文转载自:

共有 人打赏支持
法斗斗
粉丝 21
博文 367
码字总数 17774
作品 0
杨浦
程序员
私信 提问
免费的编程中文书籍索引【收藏速度】

语言无关类 优质博客 PyTab在线手册中心 ImportNew 廖雪峰的官方网站 程序员博客墙 操作系统 开源世界旅行手册 鸟哥的Linux私房菜 Linux 系统高级编程 The Linux Command Line (中英文版) L...

yonghu86
2015/04/15
0
0
Fanta/free-programming-books-zh_CN

免费的编程中文书籍索引 免费的编程中文书籍索引,欢迎投稿。 国外程序员在 stackoverflow 推荐的程序员必读书籍,中文版。 stackoverflow 上的程序员应该阅读的非编程类书籍有哪些? 中文版...

Fanta
2016/11/14
0
0
开源电子书

目录 语言无关类 操作系统 智能系统 分布式系统 编译原理 函数式概念 计算机图形学 WEB服务器 版本控制 编辑器 NoSQL PostgreSQL MySQL 管理和监控 项目相关 设计模式 Web 大数据 编程艺术 ...

zting科技
2017/12/11
0
0
SwiftLint 0.20.1 发布,Swift 代码检查及规范工具

SwiftLint 0.20.1 已发布,SwiftLint 是一个用于强制检查 Swift 代码风格和规范代码的一个工具,基本上以 GitHub's Swift 代码风格指南为基础。 SwiftLint Hook 了 Clang 和 SourceKit 从而能...

王练
2017/07/03
447
0
总有你要的编程书单(GitHub )

目录 IDE IntelliJ IDEA 简体中文专题教程 MySQL 21分钟MySQL入门教程 MySQL索引背后的数据结构及算法原理 NoSQL Disque 使用教程 Neo4j .rb 中文資源 Redis 命令参考 Redis 设计与实现 The ...

汇智网
2017/11/22
0
0

没有更多内容

加载失败,请刷新页面

加载更多

2018年终盘点:区块链真的结束了吗?

2018 年,大家依旧期待区块链出现“杀手级”应用,然而到了年关,终究还是没有。既然没有出现,只能认为“神功”尚未练成,但是这一年也没有虚度,让大家再一次领教了这个领域的跌宕起伏。 ...

酒逢知己千杯少
14分钟前
0
0
社交软件系统ThinkSNS+默认配置信息说明

感谢大家一直以来对社交软件系统ThinkSNS的关注,ThinkSNS Plus社交系统一直在不断优化完善。ThinkSNS Plus 本次于2018年12月3日更新发布。 本次重要更新说明如下: 1.优化默认配置信息,服务...

ThinkSNS账号
16分钟前
2
0
阿里云文件存储(NAS)助力业务系统承载双十一尖峰流量

2018天猫双11全球狂欢节,全天成交额再次刷新纪录达到2135亿元,其中总成交额在开场后仅仅用了2分05秒即突破100亿元,峰值的交易量达到惊人的高度,背后离不开阿里云大数据计算和存储能力的支...

阿里云官方博客
18分钟前
2
0
Frost & Sullivan权威报告:阿里云再次领跑云WAF大中华区市场

近日,国际权威分析机构Frost & Sullivan 针对Web应用防火墙(简称“WAF”)领域发布了《2017年亚太区Web应用防火墙市场报告》,阿里云以市场占有率45.8%的绝对优势连续两年领跑大中华区云WAF...

阿里云云栖社区
18分钟前
2
0
Axios使用拦截器全局处理请求重试

Axios拦截器 Axios提供了拦截器的接口,让我们能够全局处理请求和响应。Axios拦截器会在Promise的then和catch调用前拦截到。 请求拦截示例 axios.interceptors.request.use(function (conf...

kisshua
22分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部