Swift Style Guide from raywenderlich.com
全てキャメルケースで記述する。
モジュールスコープの定数とクラスは開始文字 uppercase.
関数と変数は開始文字 lowercase.
// Preffered
let MaximumWidgetCount = 100
class WidgetContainer {
var widgetButton: UIButton
let widgetHeightPercentage = 0.85
}
// Not Preferred
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)
Swift はモジュールによるネームスペース分割により名前空間の衝突を避ける事ができるので、クラス名にプレフィックスを付けるのではなく、モジュール名でアクセスする。
import MyModule
var myClass = MyModule.MyClass()
Swift を Objective-C から利用する場合は、下記の様な記述でプレフィックス付きクラス名を提供する事ができる。
@objc (RWTChicken) class Chicken {
...
}
2 spaces の設定を Xcode で行う。
ブレースは開く時は文と同じ行で。閉じる時は改行する。
// Preffered
if user.isHappy {
//Do something
} else {
//Do something else
}
// Not Preffered
if user.isHappy
{
//Do something
}
else {
//Do something else
}
メソッド内で空白行を差し込んで機能を見た目に分割しようとする事があると思いますが、多くの場合これはメソッドを分割するリファクタリングが必要なケースです。
必要であれば、コードの特定の部分が行う理由を説明するコメントを書いても良いが、常に最新の状態に保つか削除する様に気をくばる。
インラインコメントは避ける。コード自身が自己文書化されているべきである。
※ ドキュメントを生成するためのコメントは除く
構造体は値型、クラスは参照型である
構造体はアイデンティティを持たないものを定義する。生成した値 A と B は交換可能である。
クラスはアイデンティティを持つものを定義する。生成したインスタンス A と B は同一では無い。例えば Person クラスが保持しているプロパティ birthday が A と B で同一だとして、同じ人間では無い。誕生日自体は構造体として定義できるが。
歴史的経緯で AnyObject 型に適合するために構造体がクラスとして定義されているものもある。(NSDate, NSSet など)
各定義については次のように、名前とコロンの間にスペースを入れず、コロンと型名の間にスペースを入れる。var x: Int
共通の目的/コンテキストがある場合、単一の行に複数の変数や構造を定義する。var x: Int, y: Int
プロパティオブザーバやゲッター、セッターはインデントします。
var diameter: Double {
get {
return radius * 2
}
set {
radius = newValue / 2
}
}
アクセス修飾子のデフォルトは internal
であり、変更しない場合は明示する必要はない。override 時も同様。
self
はコンパイラが必要とする時(引数とプロパティ名が同一の場合、closure 内でのパラメータ参照)のみ使用する。
Protocol を適用する場合、class 宣言に記述するのでは無く、extension
を用いる。関連するメソッド定義をシンプルにまとめる事ができる。
// Preffered
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
}
// Not Preffered
class MyViewcontroller: UIViewController, UITableViewDataSource, UIScrollViewDelegate {
// all methods
}
開始ブレースは文と同じ行に書く。
シグネチャが長くなる場合は適切な箇所で改行し、インデントを加える。
func reticulateSplines(spline: [Double], adjustmentFactor: Double,
translateConstant: Int, comment: String) -> Bool {
// reticulate code goes here
}
可能な限り trailing clusure (末尾クロージャ)
を用い、引数に説明的な名称を付ける。
return SKAction.customActionWithDuration(effect.duration) { node, elapsedTime in
// more code goes here
}
attendeeList.sort { a, b in
a > b
}
できる限り Swift のネイティブ型を利用します。必要に応じて Objective-C 型へのブリッジを行います。
// Preffered
let width = 120.0 //Double
let widthString = (width as NSNumber).stringValue //String
// Not Preffered
let width: NSNumber = 120.0 //NSNumber
let widthString: NSString = width.stringValue //NSString
SpriteKit のコードでは CGFloat
を使用していますが、これはあまりにも多くの変換を必要とし、コードが複雑化するためです。
変数は var
、定数は let
で記述しますが、適切に定義すると var よりもはるかに let の方が多くなる事に気づきます。
Tip: この基準を満たすために役立つ方法として、全てを let で宣言し、コンパイラが怒った時だけ var に変更する、というものがあります。
ImplicitOptionalValue ! は viewDidLoad
で設定されるサブビューを保持するインスタンス変数のみに使用してください。
一度だけアクセスする場合や、複数のオプショナル値が連なっている場合はオプショナルチェーンを使用してください。
self.textContainer?.textLabel?.setNeedsDisplay()
アンラップして複数の操作を行った方が効率良い場合は、以下のように Optional Binding 構文
を使う。
if let textContainer = self.textContainer {
// do many things with textContainer
}
オプショナルである事は型で明らかなので、変数や定数名に optionalString
や maybeView
といった名前を付けない様にしてください。もともとの意味を隠してしまいます。
Swift ネイティブのイニシャライザではなく、従来の CGGeometryコンストラクタ
を使用してください。
// Preferred
let bounds = CGRect(x: 40, y: 20, width: 120, height: 80)
var centerPoint = CGPoint(x: 96, y: 42)
// Not Preferred
let bounds = CGRectMake(40, 20, 120, 80)
var centerPoint = CGPointMake(96, 42)
CGRectInfinite
CGRectNull
といったグローバル定数よりも CGRect.infiniteRect
CGRect.nullRect
といった構造体定数の方が、.zeroRect
といった省略系が使えるので良い。
変数、定数の型は推論に任せる。型の指定は多くの場合必要ありません。
型推論に任せるという事は、以前にも増して説明的な名付けが重要という事です。
完全なジェネリクス宣言よりも、ショートカット宣言が良いです。
// Preferred
var deviceModels: [String]
var employees: [Int: String]
var faxNumber: Int?
// Not Preferrerd
var deviceModels: Array<String>
var employees: Dictionary<Int, String>
var faxNumber: Optional<Int>
for文はインクリメントスタイルではなく for - in
スタイルが良い。
// Preffered
for _ in 0..<3 {
println("Hello three times")
}
for (index, person) in enumerate(attendeeList) {
println("\(person) is at position #\(index)")
}
// Not Preferred
for var i = 0; i < 3; i++ {
println("Hello three times")
}
for var i = 0; i < attendeeList.count; i++ {
let person = attendeeList[i]
println("\(person) is at position #\(i)")
}
コード後にセミコロンは書きません。1行には1つの式だけを書いてください。
唯一の例外は for文等のコントロールフローを記述する時ですが、これもできるだけ for-in
スタイルで書いてください。
NOTE: Swift のセミコロン省略は、一般的に安全では無いと考えられている Javascript のそれと異なります。
Apple の API に合わせて、アメリカ英語のスペルを使用してください。
// Preffered
var color = "red"
// Not Preffered
var colour = "red"
スマイリーフェイスは raywenderlich.com の特徴的なスタイルです! :)
は中途半端なので使ってはいけません。最大の笑顔を表現するために :]
を使用しましょう。