Skip to content

Instantly share code, notes, and snippets.

@taketin
Last active August 29, 2015 14:13
Show Gist options
  • Save taketin/c3404bfc92f3ea85cad1 to your computer and use it in GitHub Desktop.
Save taketin/c3404bfc92f3ea85cad1 to your computer and use it in GitHub Desktop.

Swift Style Guide from github.com

スペーシング

  • スペースではなくタブを使う。
  • ファイルの終端は改行を入れる。
  • 論理的なまとまりにコードを分割するための改行は自由に使って良い。
  • 末尾に空白を入れない。
  • 空行にインデントを入れない。

定数と変数

  • できる限り let を使用するべき。
  • var を使用することは、値に対する変更とその理由を自問する事を前提とする。

オプショナル

  • Force Unwrapping ? ! の使用を避ける。安全に扱う為に Optional Binding 構文を使う。
if let foo = foo {
    // Use unwrapped `foo` value in here
} else {
    // If appropriate, handle the case where the optional is nil
}
  • オプショナルチェーンも使用して良い。
foo?.callSomethingIfFooIsNotNil()
  • 実行時にクラッシュする恐れがあるので Implicitly Unwrapped Optional (!) は使用しないでください。

ゲッター

  • リードオンリーの計算型プロパティとサブスクリプトは、get を省略してください。
// Preffered
var myGreatProperty: Int {
    return 4
}

subscript(index: Int) -> T {
    return objects[index]
}
// Not Preffered
var myGreatProperty: Int {
    get {
        return 4
    }
}

subscript(index: Int) -> T {
    get {
        return objects[index]
    }
}

アクセス修飾子

  • トップレベルの定義では、省略することなくアクセス修飾子を定義してください。
public var whoopsGlobalState: Int
internal struct TheFez {}
private func doTheThings(things: [Thing]) {}
  • 自明な場合には、省略して暗黙値を使うことができます。
internal struct TheFez {
    var owner: Person = Joshaber()
}

型宣言

  • 名前の後に続けてコロン、その後スペースを入れ型を書く。
class SmallBatchSustainableFairtrade: Coffee { ... }

let timeToCoffee: NSTimeInterval = 2

func makeCoffee(type: CoffeeType) -> Coffee { ... }
  • 辞書の場合も同様。
let capitals: [Country: City] = [ Sweden: Stockholm ]

Self の使用

  • 基本的に self. は省略する。
  • 引数とプロパティが競合する場合、クロージャ内で参照する場合などのコンパイラが求める場合のみ self. を使う。

クラスと構造体

  • クラスよりも構造体が好ましい。
  • アイデンティティーが求められるか、deinit などのクラス特有の機能を使用したい場合以外は構造体を利用します。
  • 構造体は、ポリモーフィズムを Protocol により、実装の再利用はコンポジションにより実現する事ができます。このため、継承はクラスを利用する十分な理由にならないことに注意してください。例えば以下のクラス構造は
class Vehicle {
    let numberOfWheels: Int

    init(numberOfWheels: Int) {
        self.numberOfWheels = numberOfWheels
    }

    func maximumTotalTirePressure(pressurePerWheel: Float) -> Float {
        return pressurePerWheel * numberOfWheels
    }
}

class Bicycle: Vehicle {
    init() {
        super.init(numberOfWheels: 2)
    }
}

class Car: Vehicle {
    init() {
        super.init(numberOfWheels: 4)
    }
}
  • このようにリファクタリングできます。
protocol Vehicle {
    var numberOfWheels: Int { get }
}

func maximumTotalTirePressure(vehicle: Vehicle, pressurePerWheel: Float) -> Float {
    return pressurePerWheel * vehicle.numberOfWheels
}

struct Bicycle: Vehicle {
    let numberOfWheels = 2
}

struct Car: Vehicle {
    let numberOfWheels = 4
}
  • 上記の理由としては、値型の方がシンプルであり、 let キーワードで期待通りに動きます。

クラスはデフォルト final

  • クラスは基本 final として扱う。継承する必要が出た場合、サブクラス化を可能にするように変更しても良いが、できる限り同じルールに従わせる。

ジェネリクス

  • 型パラメータはできるだけ省略する。その方が意図が明確になる。
struct Composite<T> {
    
    func compose(other: Composite) -> Composite {
        return Composite(self, other)
    }
}
// Not Preffered
struct Composite<T> {
    
    func compose(other: Composite<T>) -> Composite<T> {
        return Composite<T>(self, other)
    }
}

オペレータ

  • オペレータは句読点文字が使用される為、読み易いように定義にはスペースを入れるようにしてください。
// Preffered
func <| (lhs: Int, rhs: Int) -> Int
func <|< <A>(lhs: A, rhs: A) -> A
// Not Preffered
func <|(lhs: Int, rhs: Int) -> Int
func <|<<A>(lhs: A, rhs: A) -> A
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment