最新消息:

Swift 编程风格指南(raywenderlich.com 版本)

Apple admin 2656浏览 0评论
本文版权归 raywenderlich.com 、The Official raywenderlich.com Swift Style Guide项目以及所有贡献者所有。译者翻译仅供知识传播使用。

本风格指南的目标是让Swift代码更简洁、可读更强。

语言

推荐使用跟苹果API文档风格统一的英语。

推荐:

<span class="kd" style="color: #66d9ef;">var</span> <span class="nx" style="color: #a6e22e;">color</span> <span class="o" style="color: #f92672;">=</span> <span class="s2" style="color: #e6db74;">"red"</span>

不推荐:

<span class="kd" style="color: #66d9ef;">var</span> <span class="nx" style="color: #a6e22e;">colour</span> <span class="o" style="color: #f92672;">=</span> <span class="s2" style="color: #e6db74;">"red"</span>

空白

  • 使用2个空白符作为缩进,不要使用Tab制表符,请务必在Xcode中进行设置;
  • 方法定义时的大括号或其它大括号(if/else/switch/while等)中的左括号写在当前语句的结尾,右括号需要另起一行。

推荐:

<span class="k" style="color: #66d9ef;">if</span> <span class="nx" style="color: #a6e22e;">user</span><span class="p" style="color: #f8f8f2;">.</span><span class="nx" style="color: #a6e22e;">isHappy</span> <span class="p" style="color: #f8f8f2;">{</span>
  <span class="c1" style="color: #75715e;">//Do something
</span><span class="p" style="color: #f8f8f2;">}</span> <span class="k" style="color: #66d9ef;">else</span> <span class="p" style="color: #f8f8f2;">{</span>
  <span class="c1" style="color: #75715e;">//Do something else
</span><span class="p" style="color: #f8f8f2;">}</span>

不推荐:

<span class="k" style="color: #66d9ef;">if</span> <span class="nx" style="color: #a6e22e;">user</span><span class="p" style="color: #f8f8f2;">.</span><span class="nx" style="color: #a6e22e;">isHappy</span>
<span class="p" style="color: #f8f8f2;">{</span>
    <span class="c1" style="color: #75715e;">//Do something
</span><span class="p" style="color: #f8f8f2;">}</span>
<span class="k" style="color: #66d9ef;">else</span> <span class="p" style="color: #f8f8f2;">{</span>
    <span class="c1" style="color: #75715e;">//Do something else
</span><span class="p" style="color: #f8f8f2;">}</span>
  • 方法定义之间需要插入一个空行,让代码在视觉上更清晰,也便于管理。方法内部也需要使用空行来分隔不同功能的代码块,但如果一个方法中有太多代码块,你最好将它们拆分为多个方法(重构)。

注释

只有在必要的时候才写注释来解释某段代码为什么那么做。注释必须跟代码同步更新,该删掉时就删掉。

尽量避免使用多行注释,而是让代码本身去解释自己的功能。

命名

使用可描述性的驼峰式命名法为类、函数、方法、变量等命名。模块中的类名和常量名首字母需要大写,而方法名和变量名的首字母需要小写。

推荐:

<span class="kd" style="color: #66d9ef;">let</span> <span class="nx" style="color: #a6e22e;">MaximumWidgetCount</span> <span class="o" style="color: #f92672;">=</span> <span class="mi" style="color: #ae81ff;">100</span>

<span class="kr" style="color: #66d9ef;">class</span> <span class="nx" style="color: #a6e22e;">WidgetContainer</span> <span class="p" style="color: #f8f8f2;">{</span>
  <span class="kd" style="color: #66d9ef;">var</span> <span class="nl" style="color: #f8f8f2;">widgetButton</span><span class="p" style="color: #f8f8f2;">:</span> <span class="nx" style="color: #a6e22e;">UIButton</span>
  <span class="kd" style="color: #66d9ef;">let</span> <span class="nx" style="color: #a6e22e;">widgetHeightPercentage</span> <span class="o" style="color: #f92672;">=</span> <span class="mf" style="color: #ae81ff;">0.85</span>
<span class="p" style="color: #f8f8f2;">}</span>

不推荐:

<span class="kd" style="color: #66d9ef;">let</span> <span class="nx" style="color: #a6e22e;">MAX_WIDGET_COUNT</span> <span class="o" style="color: #f92672;">=</span> <span class="mi" style="color: #ae81ff;">100</span>

<span class="kr" style="color: #66d9ef;">class</span> <span class="nx" style="color: #a6e22e;">app_widgetContainer</span> <span class="p" style="color: #f8f8f2;">{</span>
  <span class="kd" style="color: #66d9ef;">var</span> <span class="nl" style="color: #f8f8f2;">wBut</span><span class="p" style="color: #f8f8f2;">:</span> <span class="nx" style="color: #a6e22e;">UIButton</span>
  <span class="kd" style="color: #66d9ef;">let</span> <span class="nx" style="color: #a6e22e;">wHeightPct</span> <span class="o" style="color: #f92672;">=</span> <span class="mf" style="color: #ae81ff;">0.85</span>
<span class="p" style="color: #f8f8f2;">}</span>

对于函数和构造器(init),除非能一目了然,否则建议为每个参数命名。如果能让函数可读性更强,请提供每个参数的外部参数名。

<span class="nx" style="color: #a6e22e;">func</span> <span class="nx" style="color: #a6e22e;">dateFromString</span><span class="p" style="color: #f8f8f2;">(</span><span class="nx" style="color: #a6e22e;">dateString</span><span class="err" style="color: #960050;">:</span> <span class="nx" style="color: #a6e22e;">NSString</span><span class="p" style="color: #f8f8f2;">)</span> <span class="o" style="color: #f92672;">-&gt;</span> <span class="nx" style="color: #a6e22e;">NSDate</span>
<span class="nx" style="color: #a6e22e;">func</span> <span class="nx" style="color: #a6e22e;">convertPointAt</span><span class="p" style="color: #f8f8f2;">(</span><span class="err" style="color: #960050;">#</span><span class="nx" style="color: #a6e22e;">column</span><span class="err" style="color: #960050;">:</span> <span class="nx" style="color: #a6e22e;">Int</span><span class="p" style="color: #f8f8f2;">,</span> <span class="err" style="color: #960050;">#</span><span class="nx" style="color: #a6e22e;">row</span><span class="err" style="color: #960050;">:</span> <span class="nx" style="color: #a6e22e;">Int</span><span class="p" style="color: #f8f8f2;">)</span> <span class="o" style="color: #f92672;">-&gt;</span> <span class="nx" style="color: #a6e22e;">CGPoint</span>
<span class="nx" style="color: #a6e22e;">func</span> <span class="nx" style="color: #a6e22e;">timedAction</span><span class="p" style="color: #f8f8f2;">(</span><span class="err" style="color: #960050;">#</span><span class="nx" style="color: #a6e22e;">delay</span><span class="err" style="color: #960050;">:</span> <span class="nx" style="color: #a6e22e;">NSTimeInterval</span><span class="p" style="color: #f8f8f2;">,</span> <span class="nx" style="color: #a6e22e;">perform</span> <span class="nx" style="color: #a6e22e;">action</span><span class="err" style="color: #960050;">:</span> <span class="nx" style="color: #a6e22e;">SKAction</span><span class="p" style="color: #f8f8f2;">)</span> <span class="o" style="color: #f92672;">-&gt;</span> <span class="nx" style="color: #a6e22e;">SKAction</span><span class="o" style="color: #f92672;">!</span>

<span class="c1" style="color: #75715e;">// would be called like this:
</span><span class="nx" style="color: #a6e22e;">dateFromString</span><span class="p" style="color: #f8f8f2;">(</span><span class="s2" style="color: #e6db74;">"2014-03-14"</span><span class="p" style="color: #f8f8f2;">)</span>
<span class="nx" style="color: #a6e22e;">convertPointAt</span><span class="p" style="color: #f8f8f2;">(</span><span class="nx" style="color: #a6e22e;">column</span><span class="err" style="color: #960050;">:</span> <span class="mi" style="color: #ae81ff;">42</span><span class="p" style="color: #f8f8f2;">,</span> <span class="nx" style="color: #a6e22e;">row</span><span class="err" style="color: #960050;">:</span> <span class="mi" style="color: #ae81ff;">13</span><span class="p" style="color: #f8f8f2;">)</span>
<span class="nx" style="color: #a6e22e;">timedAction</span><span class="p" style="color: #f8f8f2;">(</span><span class="nx" style="color: #a6e22e;">delay</span><span class="err" style="color: #960050;">:</span> <span class="mf" style="color: #ae81ff;">1.0</span><span class="p" style="color: #f8f8f2;">,</span> <span class="nx" style="color: #a6e22e;">perform</span><span class="err" style="color: #960050;">:</span> <span class="nx" style="color: #a6e22e;">someOtherAction</span><span class="p" style="color: #f8f8f2;">)</span>

对于类中的方法,请遵循苹果惯例,将方法名作为第一个参数的外部名:

<span class="kr" style="color: #66d9ef;">class</span> <span class="nx" style="color: #a6e22e;">Guideline</span> <span class="p" style="color: #f8f8f2;">{</span>
  <span class="nx" style="color: #a6e22e;">func</span> <span class="nx" style="color: #a6e22e;">combineWithString</span><span class="p" style="color: #f8f8f2;">(</span><span class="nl" style="color: #f8f8f2;">incoming</span><span class="p" style="color: #f8f8f2;">:</span> <span class="nb" style="color: #f8f8f2;">String</span><span class="p" style="color: #f8f8f2;">,</span> <span class="nl" style="color: #f8f8f2;">options</span><span class="p" style="color: #f8f8f2;">:</span> <span class="nx" style="color: #a6e22e;">Dictionary</span><span class="p" style="color: #f8f8f2;">?)</span> <span class="p" style="color: #f8f8f2;">{</span> <span class="p" style="color: #f8f8f2;">...</span> <span class="p" style="color: #f8f8f2;">}</span>
  <span class="nx" style="color: #a6e22e;">func</span> <span class="nx" style="color: #a6e22e;">upvoteBy</span><span class="p" style="color: #f8f8f2;">(</span><span class="nx" style="color: #a6e22e;">amount</span><span class="p" style="color: #f8f8f2;">:</span> <span class="nx" style="color: #a6e22e;">Int</span><span class="p" style="color: #f8f8f2;">)</span> <span class="p" style="color: #f8f8f2;">{</span> <span class="p" style="color: #f8f8f2;">...</span> <span class="p" style="color: #f8f8f2;">}</span>
<span class="p" style="color: #f8f8f2;">}</span>

如果在非代码文本(包括教程、书籍以及注释中)中引用了某个函数,请提供函数所有参数的外部参数名:

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)包含了命名空间,所有在模块中定义的类型名都不会与其它模块冲突。所以我们不再需要使用前缀命名来减少命名冲突。如果两个来自不同模块的相同名字需要同时引用,你可以使用模块名+点+类型名的方式来处理:

<span class="kr" style="color: #66d9ef;">import</span> <span class="nx" style="color: #a6e22e;">MyModule</span>

<span class="kd" style="color: #66d9ef;">var</span> <span class="nx" style="color: #a6e22e;">myClass</span> <span class="o" style="color: #f92672;">=</span> <span class="nx" style="color: #a6e22e;">MyModule</span><span class="p" style="color: #f8f8f2;">.</span><span class="nx" style="color: #a6e22e;">MyClass</span><span class="p" style="color: #f8f8f2;">()</span>

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

如果你需要将Swift类型暴露给Objective-C,你可以为其指定一个在Objective-C中使用的合适前缀(请参考ObjC编程风格指南

<span class="err" style="color: #960050;">@</span><span class="nx" style="color: #a6e22e;">objc</span> <span class="p" style="color: #f8f8f2;">(</span><span class="nx" style="color: #a6e22e;">RWTChicken</span><span class="p" style="color: #f8f8f2;">)</span> <span class="kr" style="color: #66d9ef;">class</span> <span class="nx" style="color: #a6e22e;">Chicken</span> <span class="p" style="color: #f8f8f2;">{</span>
   <span class="p" style="color: #f8f8f2;">...</span>
<span class="p" style="color: #f8f8f2;">}</span>

分号

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

然而我们并不推荐这种将多行语句写在一行的做法。

唯一例外是for-conditional-increment结构,它必须使用分号。但你应该尽量使用for-in结构来替代这种行为:

推荐:

<span class="kd" style="color: #66d9ef;">var</span> <span class="nx" style="color: #a6e22e;">swift</span> <span class="o" style="color: #f92672;">=</span> <span class="s2" style="color: #e6db74;">"not a scripting language"</span>

不推荐:

<span class="kd" style="color: #66d9ef;">var</span> <span class="nx" style="color: #a6e22e;">swift</span> <span class="o" style="color: #f92672;">=</span> <span class="s2" style="color: #e6db74;">"not a scripting language"</span><span class="p" style="color: #f8f8f2;">;</span>

注意: Swift跟Javascript有很大区别,Javascript中如果忽略分号会被认为造成代码的不安全

类和结构体

请将类和结构体中的代码按以下顺序进行组织:

  • 变量和常量属性
  • 构造器
  • 公共方法
  • 私有方法
<span class="kr" style="color: #66d9ef;">class</span> <span class="nx" style="color: #a6e22e;">Circle</span><span class="err" style="color: #960050;">:</span> <span class="nx" style="color: #a6e22e;">Shape</span> <span class="p" style="color: #f8f8f2;">{</span>
  <span class="kd" style="color: #66d9ef;">var</span> <span class="nl" style="color: #f8f8f2;">x</span><span class="p" style="color: #f8f8f2;">:</span> <span class="nx" style="color: #a6e22e;">Int</span><span class="p" style="color: #f8f8f2;">,</span> <span class="nl" style="color: #f8f8f2;">y</span><span class="p" style="color: #f8f8f2;">:</span> <span class="nx" style="color: #a6e22e;">Int</span>
  <span class="kd" style="color: #66d9ef;">var</span> <span class="nl" style="color: #f8f8f2;">radius</span><span class="p" style="color: #f8f8f2;">:</span> <span class="nx" style="color: #a6e22e;">Double</span>
  <span class="kd" style="color: #66d9ef;">var</span> <span class="nl" style="color: #f8f8f2;">diameter</span><span class="p" style="color: #f8f8f2;">:</span> <span class="nx" style="color: #a6e22e;">Double</span> <span class="p" style="color: #f8f8f2;">{</span>
    <span class="nx" style="color: #a6e22e;">get</span> <span class="p" style="color: #f8f8f2;">{</span>
      <span class="k" style="color: #66d9ef;">return</span> <span class="nx" style="color: #a6e22e;">radius</span> <span class="o" style="color: #f92672;">*</span> <span class="mi" style="color: #ae81ff;">2</span>
    <span class="p" style="color: #f8f8f2;">}</span>
    <span class="nx" style="color: #a6e22e;">set</span> <span class="p" style="color: #f8f8f2;">{</span>
      <span class="nx" style="color: #a6e22e;">radius</span> <span class="o" style="color: #f92672;">=</span> <span class="nx" style="color: #a6e22e;">newValue</span> <span class="o" style="color: #f92672;">/</span> <span class="mi" style="color: #ae81ff;">2</span>
    <span class="p" style="color: #f8f8f2;">}</span>
  <span class="p" style="color: #f8f8f2;">}</span>

  <span class="nx" style="color: #a6e22e;">init</span><span class="p" style="color: #f8f8f2;">(</span><span class="nl" style="color: #f8f8f2;">x</span><span class="p" style="color: #f8f8f2;">:</span> <span class="nx" style="color: #a6e22e;">Int</span><span class="p" style="color: #f8f8f2;">,</span> <span class="nl" style="color: #f8f8f2;">y</span><span class="p" style="color: #f8f8f2;">:</span> <span class="nx" style="color: #a6e22e;">Int</span><span class="p" style="color: #f8f8f2;">,</span> <span class="nl" style="color: #f8f8f2;">radius</span><span class="p" style="color: #f8f8f2;">:</span> <span class="nx" style="color: #a6e22e;">Double</span><span class="p" style="color: #f8f8f2;">)</span> <span class="p" style="color: #f8f8f2;">{</span>
    <span class="nx" style="color: #a6e22e;">self</span><span class="p" style="color: #f8f8f2;">.</span><span class="nx" style="color: #a6e22e;">x</span> <span class="o" style="color: #f92672;">=</span> <span class="nx" style="color: #a6e22e;">x</span>
    <span class="nx" style="color: #a6e22e;">self</span><span class="p" style="color: #f8f8f2;">.</span><span class="nx" style="color: #a6e22e;">y</span> <span class="o" style="color: #f92672;">=</span> <span class="nx" style="color: #a6e22e;">y</span>
    <span class="nx" style="color: #a6e22e;">self</span><span class="p" style="color: #f8f8f2;">.</span><span class="nx" style="color: #a6e22e;">radius</span> <span class="o" style="color: #f92672;">=</span> <span class="nx" style="color: #a6e22e;">radius</span>
  <span class="p" style="color: #f8f8f2;">}</span>

  <span class="nx" style="color: #a6e22e;">convenience</span> <span class="nx" style="color: #a6e22e;">init</span><span class="p" style="color: #f8f8f2;">(</span><span class="nl" style="color: #f8f8f2;">x</span><span class="p" style="color: #f8f8f2;">:</span> <span class="nx" style="color: #a6e22e;">Int</span><span class="p" style="color: #f8f8f2;">,</span> <span class="nl" style="color: #f8f8f2;">y</span><span class="p" style="color: #f8f8f2;">:</span> <span class="nx" style="color: #a6e22e;">Int</span><span class="p" style="color: #f8f8f2;">,</span> <span class="nl" style="color: #f8f8f2;">diameter</span><span class="p" style="color: #f8f8f2;">:</span> <span class="nx" style="color: #a6e22e;">Double</span><span class="p" style="color: #f8f8f2;">)</span> <span class="p" style="color: #f8f8f2;">{</span>
    <span class="nx" style="color: #a6e22e;">self</span><span class="p" style="color: #f8f8f2;">.</span><span class="nx" style="color: #a6e22e;">init</span><span class="p" style="color: #f8f8f2;">(</span><span class="nl" style="color: #f8f8f2;">x</span><span class="p" style="color: #f8f8f2;">:</span> <span class="nx" style="color: #a6e22e;">x</span><span class="p" style="color: #f8f8f2;">,</span> <span class="nl" style="color: #f8f8f2;">y</span><span class="p" style="color: #f8f8f2;">:</span> <span class="nx" style="color: #a6e22e;">y</span><span class="p" style="color: #f8f8f2;">,</span> <span class="nl" style="color: #f8f8f2;">radius</span><span class="p" style="color: #f8f8f2;">:</span> <span class="nx" style="color: #a6e22e;">diameter</span> <span class="o" style="color: #f92672;">/</span> <span class="mi" style="color: #ae81ff;">2</span><span class="p" style="color: #f8f8f2;">)</span>
  <span class="p" style="color: #f8f8f2;">}</span>

  <span class="nx" style="color: #a6e22e;">func</span> <span class="nx" style="color: #a6e22e;">describe</span><span class="p" style="color: #f8f8f2;">()</span> <span class="o" style="color: #f92672;">-&gt;</span> <span class="nb" style="color: #f8f8f2;">String</span> <span class="p" style="color: #f8f8f2;">{</span>
    <span class="k" style="color: #66d9ef;">return</span> <span class="s2" style="color: #e6db74;">"I am a circle at ((x),(y)) with an area of (computeArea())"</span>
  <span class="p" style="color: #f8f8f2;">}</span>

  <span class="nx" style="color: #a6e22e;">func</span> <span class="nx" style="color: #a6e22e;">computeArea</span><span class="p" style="color: #f8f8f2;">()</span> <span class="o" style="color: #f92672;">-&gt;</span> <span class="nx" style="color: #a6e22e;">Double</span> <span class="p" style="color: #f8f8f2;">{</span>
    <span class="k" style="color: #66d9ef;">return</span> <span class="nx" style="color: #a6e22e;">M_PI</span> <span class="o" style="color: #f92672;">*</span> <span class="nx" style="color: #a6e22e;">radius</span> <span class="o" style="color: #f92672;">*</span> <span class="nx" style="color: #a6e22e;">radius</span>
  <span class="p" style="color: #f8f8f2;">}</span>
<span class="p" style="color: #f8f8f2;">}</span>

上面的例子还展示了以下风格:

  • 定义属性、变量、常量、参数以及其他语句时,在其后面加上空格,而不是在前面加。比如说,x: Int 和 Circle: Shape
  • 属性的gettersetter以及属性观察器willSetdidSet的实现都需要缩进;
  • 如果多个变量和结构体有相同的使用目的或使用环境,可以将它们定义在同一行代码中。

Self 的使用

请避免在Swift中使用self,因为我们不需要使用self来访问一个对象的属性或调用它的方法。

唯一需要使用的场景是在类或结构体的构造器中。你可以使用self来区分传入的参数和类/结构体的属性:

<span class="kr" style="color: #66d9ef;">class</span> <span class="nx" style="color: #a6e22e;">BoardLocation</span> <span class="p" style="color: #f8f8f2;">{</span>
  <span class="kd" style="color: #66d9ef;">let</span> <span class="nl" style="color: #f8f8f2;">row</span><span class="p" style="color: #f8f8f2;">:</span> <span class="nx" style="color: #a6e22e;">Int</span><span class="p" style="color: #f8f8f2;">,</span> <span class="nl" style="color: #f8f8f2;">column</span><span class="p" style="color: #f8f8f2;">:</span> <span class="nx" style="color: #a6e22e;">Int</span>

  <span class="nx" style="color: #a6e22e;">init</span><span class="p" style="color: #f8f8f2;">(</span><span class="nl" style="color: #f8f8f2;">row</span><span class="p" style="color: #f8f8f2;">:</span> <span class="nx" style="color: #a6e22e;">Int</span><span class="p" style="color: #f8f8f2;">,</span><span class="nl" style="color: #f8f8f2;">column</span><span class="p" style="color: #f8f8f2;">:</span> <span class="nx" style="color: #a6e22e;">Int</span><span class="p" style="color: #f8f8f2;">)</span> <span class="p" style="color: #f8f8f2;">{</span>
    <span class="nx" style="color: #a6e22e;">self</span><span class="p" style="color: #f8f8f2;">.</span><span class="nx" style="color: #a6e22e;">row</span> <span class="o" style="color: #f92672;">=</span> <span class="nx" style="color: #a6e22e;">row</span>
    <span class="nx" style="color: #a6e22e;">self</span><span class="p" style="color: #f8f8f2;">.</span><span class="nx" style="color: #a6e22e;">column</span> <span class="o" style="color: #f92672;">=</span> <span class="nx" style="color: #a6e22e;">column</span>
  <span class="p" style="color: #f8f8f2;">}</span>
<span class="p" style="color: #f8f8f2;">}</span>

函数定义

尽量将较短的函数名定义在一行,并以一个左大括号结尾:

<span class="nx" style="color: #a6e22e;">func</span> <span class="nx" style="color: #a6e22e;">reticulateSplines</span><span class="p" style="color: #f8f8f2;">(</span><span class="nx" style="color: #a6e22e;">spline</span><span class="err" style="color: #960050;">:</span> <span class="nx" style="color: #a6e22e;">Double</span><span class="p" style="color: #f8f8f2;">[])</span> <span class="o" style="color: #f92672;">-&gt;</span> <span class="nx" style="color: #a6e22e;">Bool</span> <span class="p" style="color: #f8f8f2;">{</span>
  <span class="c1" style="color: #75715e;">// reticulate code goes here
</span><span class="p" style="color: #f8f8f2;">}</span>

如果函数名较长,请在适当的时候换行,并对下一行函数名进行缩进:

<span class="nx" style="color: #a6e22e;">func</span> <span class="nx" style="color: #a6e22e;">reticulateSplines</span><span class="p" style="color: #f8f8f2;">(</span><span class="nx" style="color: #a6e22e;">spline</span><span class="err" style="color: #960050;">:</span> <span class="nx" style="color: #a6e22e;">Double</span><span class="p" style="color: #f8f8f2;">[],</span> <span class="nx" style="color: #a6e22e;">adjustmentFactor</span><span class="err" style="color: #960050;">:</span> <span class="nx" style="color: #a6e22e;">Double</span><span class="p" style="color: #f8f8f2;">,</span>
    <span class="nx" style="color: #a6e22e;">translateConstant</span><span class="err" style="color: #960050;">:</span> <span class="nx" style="color: #a6e22e;">Int</span><span class="p" style="color: #f8f8f2;">,</span> <span class="nx" style="color: #a6e22e;">comment</span><span class="err" style="color: #960050;">:</span> <span class="nb" style="color: #f8f8f2;">String</span><span class="p" style="color: #f8f8f2;">)</span> <span class="o" style="color: #f92672;">-&gt;</span> <span class="nx" style="color: #a6e22e;">Bool</span> <span class="p" style="color: #f8f8f2;">{</span>
  <span class="c1" style="color: #75715e;">// reticulate code goes here
</span><span class="p" style="color: #f8f8f2;">}</span>

闭包

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

<span class="k" style="color: #66d9ef;">return</span> <span class="nx" style="color: #a6e22e;">SKAction</span><span class="p" style="color: #f8f8f2;">.</span><span class="nx" style="color: #a6e22e;">customActionWithDuration</span><span class="p" style="color: #f8f8f2;">(</span><span class="nx" style="color: #a6e22e;">effect</span><span class="p" style="color: #f8f8f2;">.</span><span class="nx" style="color: #a6e22e;">duration</span><span class="p" style="color: #f8f8f2;">)</span> <span class="p" style="color: #f8f8f2;">{</span> <span class="nx" style="color: #a6e22e;">node</span><span class="p" style="color: #f8f8f2;">,</span> <span class="nx" style="color: #a6e22e;">elapsedTime</span> <span class="k" style="color: #66d9ef;">in</span>
  <span class="c1" style="color: #75715e;">// more code goes here
</span><span class="p" style="color: #f8f8f2;">}</span>

笔者:@aemaeth 提出将闭包参数另起一行的写法,我认为更合理,解决了多个闭包参数过长的问题。

对于一行表达式闭包,当使用场景明确时,可以使用隐式返回:

<span class="nx" style="color: #a6e22e;">attendeeList</span><span class="p" style="color: #f8f8f2;">.</span><span class="nx" style="color: #a6e22e;">sort</span> <span class="p" style="color: #f8f8f2;">{</span> <span class="nx" style="color: #a6e22e;">a</span><span class="p" style="color: #f8f8f2;">,</span> <span class="nx" style="color: #a6e22e;">b</span> <span class="k" style="color: #66d9ef;">in</span>
  <span class="nx" style="color: #a6e22e;">a</span> <span class="o" style="color: #f92672;">&gt;</span> <span class="nx" style="color: #a6e22e;">b</span>
<span class="p" style="color: #f8f8f2;">}</span>

类型

请尽量使用Swift提供的原生类型。Swift也提供了原生类型对象桥接到Objective-C对象的办法,所以必要时你能随意使用这些桥接对象提供的方法。

推荐:

<span class="kd" style="color: #66d9ef;">let</span> <span class="nx" style="color: #a6e22e;">width</span> <span class="o" style="color: #f92672;">=</span> <span class="mf" style="color: #ae81ff;">120.0</span>                                           <span class="c1" style="color: #75715e;">//Double
</span><span class="kd" style="color: #66d9ef;">let</span> <span class="nx" style="color: #a6e22e;">widthString</span> <span class="o" style="color: #f92672;">=</span> <span class="nx" style="color: #a6e22e;">width</span><span class="p" style="color: #f8f8f2;">.</span><span class="nx" style="color: #a6e22e;">bridgeToObjectiveC</span><span class="p" style="color: #f8f8f2;">().</span><span class="nx" style="color: #a6e22e;">stringValue</span>    <span class="c1" style="color: #75715e;">//String
</span>

不推荐:

<span class="kd" style="color: #66d9ef;">let</span> <span class="nx" style="color: #a6e22e;">width</span><span class="err" style="color: #960050;">:</span> <span class="nx" style="color: #a6e22e;">NSNumber</span> <span class="o" style="color: #f92672;">=</span> <span class="mf" style="color: #ae81ff;">120.0</span>                                 <span class="c1" style="color: #75715e;">//NSNumber
</span><span class="kd" style="color: #66d9ef;">let</span> <span class="nx" style="color: #a6e22e;">widthString</span><span class="err" style="color: #960050;">:</span> <span class="nx" style="color: #a6e22e;">NSString</span> <span class="o" style="color: #f92672;">=</span> <span class="nx" style="color: #a6e22e;">width</span><span class="p" style="color: #f8f8f2;">.</span><span class="nx" style="color: #a6e22e;">stringValue</span>               <span class="c1" style="color: #75715e;">//NSString
</span>

Sprite Kit代码中,请多使用CGFloat,这样代码会更简洁,也能避免非常多的类型转换。

常量

常量使用let关键字定义,而变量使用var关键字定义。

如果一个值是常量,那就必须使用let关键字来准确定义。最终你会发现,你使用let的频率远大于var

小技巧:一开始你可以将所有值都定义为常量,然后如果编译器报错了再作适当的调整。

可选

如果可以接受nil值,请将变量或函数返回值的类型定义为可选类型(加?)。

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

当访问一个可选值时,如果只访问一次,或者方式时有多种可能性,请使用可选链:

<span class="nx" style="color: #a6e22e;">myOptional</span><span class="p" style="color: #f8f8f2;">?.</span><span class="nx" style="color: #a6e22e;">anotherOne</span><span class="p" style="color: #f8f8f2;">?.</span><span class="nx" style="color: #a6e22e;">optionalView</span><span class="p" style="color: #f8f8f2;">?.</span><span class="nx" style="color: #a6e22e;">setNeedsDisplay</span><span class="p" style="color: #f8f8f2;">()</span>

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

<span class="k" style="color: #66d9ef;">if</span> <span class="kd" style="color: #66d9ef;">let</span> <span class="nx" style="color: #a6e22e;">view</span> <span class="o" style="color: #f92672;">=</span> <span class="nx" style="color: #a6e22e;">self</span><span class="p" style="color: #f8f8f2;">.</span><span class="nx" style="color: #a6e22e;">optionalView</span> <span class="p" style="color: #f8f8f2;">{</span>
  <span class="c1" style="color: #75715e;">// do many things with view
</span><span class="p" style="color: #f8f8f2;">}</span>

类型推断

Swift编译器可以推断出变量和常量的类型。你可以为每个常量或变量提供一个显示的类型(加个冒号,并在后面写上类型名),但大部分情况不必这么做。

我们建议多使用类型推断让编译器自动推断出常量或变量的类型,这样代码会更紧凑。

推荐:

<span class="kd" style="color: #66d9ef;">let</span> <span class="nx" style="color: #a6e22e;">message</span> <span class="o" style="color: #f92672;">=</span> <span class="s2" style="color: #e6db74;">"Click the button"</span>
<span class="kd" style="color: #66d9ef;">var</span> <span class="nx" style="color: #a6e22e;">currentBounds</span> <span class="o" style="color: #f92672;">=</span> <span class="nx" style="color: #a6e22e;">computeViewBounds</span><span class="p" style="color: #f8f8f2;">()</span>

不推荐:

<span class="kd" style="color: #66d9ef;">let</span> <span class="nx" style="color: #a6e22e;">message</span><span class="err" style="color: #960050;">:</span> <span class="nb" style="color: #f8f8f2;">String</span> <span class="o" style="color: #f92672;">=</span> <span class="s2" style="color: #e6db74;">"Click the button"</span>
<span class="kd" style="color: #66d9ef;">var</span> <span class="nx" style="color: #a6e22e;">currentBounds</span><span class="err" style="color: #960050;">:</span> <span class="nx" style="color: #a6e22e;">CGRect</span> <span class="o" style="color: #f92672;">=</span> <span class="nx" style="color: #a6e22e;">computeViewBounds</span><span class="p" style="color: #f8f8f2;">()</span>

注意:遵循此规则意味着在命名时,需要更慎重的选择具有描述性的名字。

流程控制

建议多使用for-in风格的for循环,而不是传统的for-condition-increment风格。

推荐:

<span class="k" style="color: #66d9ef;">for</span> <span class="nx" style="color: #a6e22e;">_</span> <span class="k" style="color: #66d9ef;">in</span> <span class="mi" style="color: #ae81ff;">0</span><span class="p" style="color: #f8f8f2;">..</span><span class="mi" style="color: #ae81ff;">5</span> <span class="p" style="color: #f8f8f2;">{</span>
  <span class="nx" style="color: #a6e22e;">println</span><span class="p" style="color: #f8f8f2;">(</span><span class="s2" style="color: #e6db74;">"Hello five times"</span><span class="p" style="color: #f8f8f2;">)</span>
<span class="p" style="color: #f8f8f2;">}</span>

<span class="k" style="color: #66d9ef;">for</span> <span class="nx" style="color: #a6e22e;">person</span> <span class="k" style="color: #66d9ef;">in</span> <span class="nx" style="color: #a6e22e;">attendeeList</span> <span class="p" style="color: #f8f8f2;">{</span>
  <span class="c1" style="color: #75715e;">// do something
</span><span class="p" style="color: #f8f8f2;">}</span>

不推荐:

<span class="k" style="color: #66d9ef;">for</span> <span class="kd" style="color: #66d9ef;">var</span> <span class="nx" style="color: #a6e22e;">i</span> <span class="o" style="color: #f92672;">=</span> <span class="mi" style="color: #ae81ff;">0</span><span class="p" style="color: #f8f8f2;">;</span> <span class="nx" style="color: #a6e22e;">i</span> <span class="o" style="color: #f92672;">&lt;</span> <span class="mi" style="color: #ae81ff;">5</span><span class="p" style="color: #f8f8f2;">;</span> <span class="nx" style="color: #a6e22e;">i</span><span class="o" style="color: #f92672;">++</span> <span class="p" style="color: #f8f8f2;">{</span>
  <span class="nx" style="color: #a6e22e;">println</span><span class="p" style="color: #f8f8f2;">(</span><span class="s2" style="color: #e6db74;">"Hello five times"</span><span class="p" style="color: #f8f8f2;">)</span>
<span class="p" style="color: #f8f8f2;">}</span>

<span class="k" style="color: #66d9ef;">for</span> <span class="kd" style="color: #66d9ef;">var</span> <span class="nx" style="color: #a6e22e;">i</span> <span class="o" style="color: #f92672;">=</span> <span class="mi" style="color: #ae81ff;">0</span><span class="p" style="color: #f8f8f2;">;</span> <span class="nx" style="color: #a6e22e;">i</span> <span class="o" style="color: #f92672;">&lt;</span> <span class="nx" style="color: #a6e22e;">attendeeList</span><span class="p" style="color: #f8f8f2;">.</span><span class="nx" style="color: #a6e22e;">count</span><span class="p" style="color: #f8f8f2;">;</span> <span class="nx" style="color: #a6e22e;">i</span><span class="o" style="color: #f92672;">++</span> <span class="p" style="color: #f8f8f2;">{</span>
  <span class="kd" style="color: #66d9ef;">let</span> <span class="nx" style="color: #a6e22e;">person</span> <span class="o" style="color: #f92672;">=</span> <span class="nx" style="color: #a6e22e;">attendeeList</span><span class="p" style="color: #f8f8f2;">[</span><span class="nx" style="color: #a6e22e;">i</span><span class="p" style="color: #f8f8f2;">]</span>
  <span class="c1" style="color: #75715e;">// do something
</span><span class="p" style="color: #f8f8f2;">}</span>

笑脸

笑脸在raywenderlich.com网站中是一个非常突出的特性。正确的使用笑脸来表达在编程时的一种极大的快乐和兴奋,至关重要。我们使用右方括号],因为它代表了ASCII艺术字符中最大的微笑;而使用右小括号)的笑脸显得有点不那么诚心,所以我们不推荐使用。

推荐:

:]

不推荐:

:)

转载请注明:爱开源 » Swift 编程风格指南(raywenderlich.com 版本)

您必须 登录 才能发表评论!