Swift 编程风格指南

1. 命名


使用驼峰式命名法,结构体枚举协议的首字母应该大写,而方法变量名首字母则小写。

private let maximumWidgetCount = 100

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

1.1 枚举

对于枚举值,应该使用首字母小写的驼峰命名法:

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

1.2 类名前缀(Class Prefix)

Swift 类型自动为模块名设置了命名空间,所以没有必要为 Swift 的类型添加类似 KS 这样的前缀了。如果两个来自不同模块的命名冲突了了,你可以在它们前面添加模块名来避免冲突。

import SomeModule

let myClass = MyModule.UsefulClass()

1.3 泛型

泛型名应该有较好的阅读性,用首字母大写的驼峰式命名。当一个类型没有有意义的关系和角色,使用传统的 TUV 来替代。

struct Stack<Element> { ... }
func writeTo<Target: OutputStream>(inout target: Target)
func max<T: Comparable>(x: T, _ y: T) -> T

1.4 语言

使用美式英语,更符合苹果的 API 标准。

2. 代码结构


2.1 代码分块

使用// MARK: -对代码进行分块组织,代码的组织顺序从整体上尽量符合我们的认知顺序。

2.2 无用代码

对于无用的代码,都应该被删掉。

2.3 最小引用

import你需要的模块。比如,如果引用Foundation以及足够,就不要再引用UIKit了。

3. 类和结构体


3.1 选择哪个?

结构体是值类型,类是引用类型。

按照通用的准则,当符合一条或多条以下条件时,请考虑构建结构体:

  • 该数据结构的主要目的是用来封装少量相关简单数据值。
  • 有理由预计该数据结构的实例在被赋值或传递时,封装的数据将会被拷贝而不是被引用。
  • 该数据结构中储存的值类型属性,也应该被拷贝,而不是被引用。
  • 该数据结构不需要去继承另一个既有类型的属性或者行为。

3.2 Self 的使用

为了保持简洁,避免使用 self 关键词,Swift 不需要使用 self 来访问对象属性和调用对象方法。

在以下情况中需要使用self

  • 在构造器中,为了区分传入的参数和属性
  • 在闭包中访问属性
class BoardLocation {
  let row: Int, column: Int

  init(row: Int, column: Int) {
    self.row = row
    self.column = column

    let closure = {
      println(self.row)
    }
  }
}

3.3 计算属性

如果一个计算属性是只读的,忽略 get 语句。只有在需要定义 set 语句的时候,才提供 get 语句。

var diameter: Double {
  return radius * 2
}

3.4 Final

如果类不会被继承,那么用关键词 final 标记。

final class Box<T> {
    let value: T 
    init(_ value: T) {
        self.value = value
    }
}

4. 协议遵守


当我们对一个类添加协议时,推荐使用一个单独的类扩展来实现协议的方法。这可以保持协议相关的方法聚合在一起,同时也可以简单的标识出一个协议对应类中需要实现哪些对应的方法。

推荐做法:

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
}

5. 函数声明


保证短的函数定义在同一行中,并且包含左大括号:

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

在一个长的函数定义时,在适当的地方进行换行,同时在下一行中添加一个额外的缩进:

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

6. 闭包表达式


详细参考:Swift 中的闭包

7. 类型


尽可能使用 Swift 原生类型。

7.1 常量

常量定义使用 let 关键字,变量定义使用 var 关键字,如果变量的值不需要改变,请尽量使用 let 关键字。
提示:一个好的技巧是,使用 let 定义任何东西,只有在编译器告诉我们值需要改变的时候才改成 var 定义。

7.2 可选类型

当一个变量或函数返回值可以为 nil 时,用 ? 将其声明为可选类型。

当确定变量在使用前被初始化,使用 ! 来解包。

必要时,使用可选值链:

self.textContainer?.textLabel?.setNeedsDisplay()

对于需要将可选值解包,并多出使用的情况,使用可选值绑定:

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

当我们命名一个可选变量和属性时,避免使用诸如 optionalString 和 maybeView 这样的命名,因为可选值的表达已经在类型定义中了。

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

推荐做法:

var subview: UIView?
var volume: Double?

// later on...
if let subview = subview, volume = volume {
  // do something with unwrapped subview and volume
}

7.3 语法糖

推荐使用简短的类型声明。

推荐做法:

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

不推荐做法:

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

8. 控制流


使用循环时,推荐用 for-in 表达式,而不是 for-condition-increment 表达式。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容