Edited at

SwiftLintの全ルール一覧(Swift 4.2版)


はじめに

すでに SwiftLintのルールをまとめてくださっている方 がいらっしゃいますが、約2年ほど更新されていなかったので、自分でもまとめてみました。

SwiftLintの概要や導入については以下をご参照ください。

Swiftの静的解析ツール「SwiftLint」のセットアップ方法 - Qiita


注意

公式ページのルールを簡単に翻訳してまとめたものです。

英語に慣れている方は公式ページを直接見るのがいいです。

https://github.com/realm/SwiftLint/blob/master/Rules.md

また、間違っている箇所や不適切な箇所がありましたら教えていただけると嬉しいです。


環境


  • Swift:4.2.1

  • Xcode:10.1 (10B61)

  • SwiftLint:0.30.1


Default

デフォルトで有効になっているルールの一覧です。


Block Based KVO

Swift 3.2以降の場合、新しいブロックベースのKVO APIとキーパスを使うべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#block-based-kvo

// bad

class Foo: NSObject {
override func observeValue(forKeyPath keyPath: String?, of object: Any?,
change: [NSKeyValueChangeKey: Any]?,
context: UnsafeMutableRawPointer?) { }
}

// good
let observer = foo.observe(\.value, options: [.new]) { (foo, change) in
print(change.newValue)
}


Class Delegate Protocol

デリゲートプロトコルはクラスのみであるべきで、弱参照されることができます。

https://github.com/realm/SwiftLint/blob/master/Rules.md#class-delegate-protocol

// bad

protocol FooDelegate { }

// good
protocol FooDelegate: class { }


Closing Brace Spacing

右括弧で閉じ括弧を閉じる場合、間にスペースを含めるべきではありません。

https://github.com/realm/SwiftLint/blob/master/Rules.md#closing-brace-spacing

// bad

[].map({ } )

// good
[].map({ })


Closure Parameter Position

クロージャのパラメータは開き括弧と同じ行にあるべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#closure-parameter-position

// bad

[1, 2].map {
number in
number + 1
}

// good
[1, 2].map { number in
number + 1
}


Colon

: は、型の指定時には識別子の後ろ、ディクショナリではキーの後ろにあるべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#colon

// bad

let abc:Void
let abc :Void
let abc : Void
let abc: [String:Int]
let abc: [String :Int]
let abc: [String : Int]

// good
let abc: Void
let abc: [String: Int]


Comma Spacing

カンマの前にスペースがあるべきではなく、カンマの後ろには1つの半角スペースがあるべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#comma-spacing

// bad

func abc(a: String,b: String) { }
func abc(a: String ,b: String) { }
func abc(a: String , b: String) { }

// good
func abc(a: String, b: String) { }


Compiler Protocol Init

ExpressibleByArrayLiteral のようなコンパイルプロトコルで定義されているイニシャライザは直接呼び出すべきではありません。

https://github.com/realm/SwiftLint/blob/master/Rules.md#compiler-protocol-init

// bad

let set = Set(arrayLiteral: 1, 2)
let set = Set.init(arrayLiteral: 1, 2)

// good
let set: Set<Int> = [1, 2]
let set = Set(array)


Control Statement

if , for , guard , switch , while , catch 文は条件や引数を不必要に括弧で括るべきではありません。

https://github.com/realm/SwiftLint/blob/master/Rules.md#control-statement

// bad

if (condition) { }
for (item in collection) { }
guard (condition) else { }
switch (foo) { }
while (condition) { }
do {
} catch (let error) {
}

// good
if condition { }
for item in collection { }
guard condition else { }
switch foo { }
while condition { }
do {
} catch let error {
}


Custom Rules

正規表現を指定してカスタムルールを作成できます。

https://github.com/realm/SwiftLint/blob/master/Rules.md#custom-rules


Cyclomatic Complexity

関数内は複雑にすべきではありません。

https://github.com/realm/SwiftLint/blob/master/Rules.md#cyclomatic-complexity

// bad

func f1() {
if true {
if true {
if false { }
}
}
if false { }
let i = 0

switch i {
case 1: break
case 2: break
case 3: break
case 4: break
default: break
}
for _ in 1...5 {
guard true else {
return
}
}
}

// good
func f1() {
if true {
for _ in 1..5 { } }
if false { }
}


Deployment Target

可用性のチェックまたは属性は、デプロイメントターゲットが満たす古いバージョンを使うべきではありません。

https://github.com/realm/SwiftLint/blob/master/Rules.md#deployment-target

// bad

@available(iOS 6.0, *)
class A { }

if #available(iOS 6.0, *) { }

// good
@available(iOS 12.0, *)
class A { }

if #available(iOS 12.0, *) { }


Discarded Notification Center Observer

ブロックを使って通知を登録するとき、返される不透明なオブザーバは後で削除できるように格納すべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#discarded-notification-center-observer

// bad

nc.addObserver(forName: .NSSystemTimeZoneDidChange, object: nil, queue: nil) { }

// good
let foo = nc.addObserver(forName: .NSSystemTimeZoneDidChange, object: nil, queue: nil) { }


Discouraged Direct Initialization

有害な可能性がある型を直接初期化すべきではありません。

https://github.com/realm/SwiftLint/blob/master/Rules.md#discouraged-direct-initialization

// bad

let foo = UIDevice()
let foo = Bundle()

// good
let foo = UIDevice.current
let foo = Bundle.main
let foo = Bundle(path: "bar")
let foo = Bundle(identifier: "bar")


Duplicate Imports

インポートは1回のみ行うべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#duplicate-imports

// bad

import Foundation
import Dispatch
import Foundation

// good
import Foundation
import Dispatch


Dynamic Inline

dynamic@inline(__always) を同時に使ってはいけません。

https://github.com/realm/SwiftLint/blob/master/Rules.md#dynamic-inline

// bad

class C {
@inline(__always) dynamic func f() { }
}

// good
class C {
dynamic func f() { }
}
class C {
@inline(__always) func f() { }
}


Empty Enum Arguments

列挙型が連想型と一致しない場合、引数を省略すべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#empty-enum-arguments

// bad

switch foo {
case .bar(_): break
}
switch foo {
case .bar(): break
}

// good
switch foo {
case .bar: break
}


Empty Parameters

Void -> より () -> を使うべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#empty-parameters

// bad

let abc: (Void) -> Void = { }

// good
let abc: () -> Void = { }


Empty Parentheses with Trailing Closure

トレイリングクロージャを使う場合、メソッドの呼び出し後に空の括弧を記述すべきではありません。

https://github.com/realm/SwiftLint/blob/master/Rules.md#empty-parentheses-with-trailing-closure

// bad

[1, 2].map() { $0 + 1 }

// good
[1, 2].map { $0 + 1 }


File Line Length

ファイル内はあまりにも多くの行にまたがるべきではないです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#file-line-length

// bad

print("swiftlint")
print("swiftlint")
print("swiftlint")


For Where

for文内にif文が1つのみ存在する場合、 where 句を使うべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#for-where

// bad

for user in users {
if user.id == 1 {
user.myFunction()
}
}

// good
for user in users where user.id == 1 {
user.myFunction()
}


Force Cast

強制キャスト( as! )は使うべきではありません。

https://github.com/realm/SwiftLint/blob/master/Rules.md#force-cast

// bad

NSNumber() as! Int

// good
NSNumber() as? Int


Force Try

強制トライ( try! )は使うべきではありません。

https://github.com/realm/SwiftLint/blob/master/Rules.md#force-try

func a() throws { }

// bad
try! a()

// good
do {
try a()
} catch {
// エラー処理
}


Function Body Length

関数内はあまりにも多くの行にまたがるべきではないです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#function-body-length


Function Parameter Count

関数の引数の数は少なくすべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#function-parameter-count

// bad

func f(a: Int, b: Int, c: Int, d: Int, e: Int, f: Int) { }

// good
func f(a: Int, b: Int, c: Int, d: Int, e: Int) { }


Generic Type Name

ジェネリック型は英数のみを含み、大文字で始まり、1〜20文字にすべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#generic-type-name

// bad

func foo<T, U_Foo>(param: U_Foo) -> T { }
func foo<T, u>(param: u) -> T { }

// good
func foo<T, U>(param: U) -> T { }


Identifier Name

識別子名は英数のみを含み、小文字で始まるか、大文字のみを含むべきです。

上記以外では、変数名は静的かつ不変と定義されている場合は大文字から始まることがあります。

変数名は長過ぎたり短過ぎたりしてはいけません。

https://github.com/realm/SwiftLint/blob/master/Rules.md#identifier-name

// bad

let MyLet = 0
let _myLet = 0
let id = 0

// good
let myLet = 0


Implicit Getter

読取専用のコンピューテッドプロパティとサブスクリプトには get キーワードを使うべきではありません。

https://github.com/realm/SwiftLint/blob/master/Rules.md#implicit-getter

// bad

class Foo {
var foo: Int {
get {
return 20
}
}
}

// good
class Foo {
var foo: Int {
return 20
}
}


Inert Defer

defer が親スコープの終わりにある場合、その場所で実行されます。

https://github.com/realm/SwiftLint/blob/master/Rules.md#inert-defer

// bad

func example() {
print("other code")
defer { /* deferred code */ }
}

// good
func example() {
defer { /* deferred code */ }
print("other code")
}


Is Disjoint

Set.intersection(_:).isEmpty より Set.isDisjoint(with:) を使うべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#is-disjoint

// bad

_ = Set(syntaxKinds).intersection(commentAndStringKindsSet).isEmpty

// good
_ = Set(syntaxKinds).isDisjoint(with: commentAndStringKindsSet)


Large Tuple

タプルはあまりにも多くのメンバーを持つべきではありません。

代わりにカスタムタイプを作成すべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#large-tuple

// bad

let foo: (Int, Int, Int)

// good
let foo: (Int, Int)


Leading Whitespace

ファイルは先頭にスペースを含んではいけません。

https://github.com/realm/SwiftLint/blob/master/Rules.md#leading-whitespace

// bad

// foo

// good
// foo


Legacy CGGeometry Functions

構造体のエクステンションのプロパティとメソッドは、従来の関数より優先すべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#legacy-cggeometry-functions

// bad

CGRectGetWidth(rect)
CGRectGetHeight(rect)
CGRectGetMinX(rect)
CGRectGetMidX(rect)
CGRectGetMaxX(rect)
CGRectGetMinY(rect)
CGRectGetMidY(rect)
CGRectGetMaxY(rect)
CGRectIsNull(rect)
CGRectIsEmpty(rect)
CGRectIsInfinite(rect)
CGRectStandardize(rect)
CGRectIntegral(rect)
CGRectInset(rect, 10, 5)
CGRectOffset(rect, -2, 8.3)
CGRectUnion(rect1, rect2)
CGRectIntersection(rect1, rect2)
CGRectContainsRect(rect1, rect2)
CGRectContainsPoint(rect, point)
CGRectIntersectsRect(rect1, rect2)

// good
rect.width
rect.height
rect.minX
rect.midX
rect.maxX
rect.minY
rect.midY
rect.maxY
rect.isNull
rect.isEmpty
rect.isInfinite
rect.standardized
rect.integral
rect.insetBy(dx: 5.0, dy: -7.0)
rect.offsetBy(dx: 5.0, dy: -7.0)
rect1.union(rect2)
rect1.intersect(rect2)
rect1.contains(rect2)
rect.contains(point)
rect1.intersects(rect2)


Legacy Constant

構造スコープ定数は従来のグローバル定数より優先すべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#legacy-constant

// bad

CGRectInfinite
CGPointZero
CGRectZero
CGSizeZero
NSZeroPoint
NSZeroRect
NSZeroSize
CGRectNull
CGFloat(M_PI)
Float(M_PI)

// good
CGRect.infinite
CGPoint.zero
CGRect.zero
CGSize.zero
NSPoint.zero
NSRect.zero
NSSize.zero
CGRect.null
CGFloat.pi
Float.pi


Legacy Constructor

Swiftのコンストラクタは従来のコンビニエンス関数より優先すべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#legacy-constructor

// bad

CGPointMake(10, 10)
CGPointMake(xVal, yVal)
CGPointMake(calculateX(), 10)
CGSizeMake(10, 10)
CGSizeMake(aWidth, aHeight)
CGRectMake(0, 0, 10, 10)
CGRectMake(xVal, yVal, width, height)
CGVectorMake(10, 10)
CGVectorMake(deltaX, deltaY)
NSMakePoint(10, 10)
NSMakePoint(xVal, yVal)
NSMakeSize(10, 10)
NSMakeSize(aWidth, aHeight)
NSMakeRect(0, 0, 10, 10)
NSMakeRect(xVal, yVal, width, height)
NSMakeRange(10, 1)
NSMakeRange(loc, len)
UIEdgeInsetsMake(0, 0, 10, 10)
UIEdgeInsetsMake(top, left, bottom, right)
NSEdgeInsetsMake(0, 0, 10, 10)
NSEdgeInsetsMake(top, left, bottom, right)
CGVectorMake(10, 10)
NSMakeRange(10, 1)
UIOffsetMake(0, 10)
UIOffsetMake(horizontal, vertical)

// good
CGPoint(x: 10, y: 10)
CGPoint(x: xValue, y: yValue)
CGSize(width: 10, height: 10)
CGSize(width: aWidth, height: aHeight)
CGRect(x: 0, y: 0, width: 10, height: 10)
CGRect(x: xVal, y: yVal, width: aWidth, height: aHeight)
CGVector(dx: 10, dy: 10)
CGVector(dx: deltaX, dy: deltaY)
NSPoint(x: 10, y: 10)
NSPoint(x: xValue, y: yValue)
NSSize(width: 10, height: 10)
NSSize(width: aWidth, height: aHeight)
NSRect(x: 0, y: 0, width: 10, height: 10)
NSRect(x: xVal, y: yVal, width: aWidth, height: aHeight)
NSRange(location: 10, length: 1)
NSRange(location: loc, length: len)
UIEdgeInsets(top: 0, left: 0, bottom: 10, right: 10)
UIEdgeInsets(top: aTop, left: aLeft, bottom: aBottom, right: aRight)
NSEdgeInsets(top: 0, left: 0, bottom: 10, right: 10)
NSEdgeInsets(top: aTop, left: aLeft, bottom: aBottom, right: aRight)
UIOffset(horizontal: 0, vertical: 10)
UIOffset(horizontal: horizontal, vertical: vertical)


Legacy Hashing

hashValue をオーバーライドするのではなく、 hash(info:) 関数を使うべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#legacy-hashing

// bad

struct Foo: Hashable {
let bar: Int = 10

public var hashValue: Int {
return bar
}
}

// good
struct Foo: Hashable {
let bar: Int = 10

func hash(into hasher: inout Hasher) {
hasher.combine(bar)
}
}


Legacy NSGeometry Functions

従来の関数より構造体のエクステンションのプロパティとメソッドを使うべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#legacy-nsgeometry-functions

// bad

NSWidth(rect)
NSHeight(rect)
NSMinX(rect)
NSMidX(rect)
NSMaxX(rect)
NSMinY(rect)
NSMidY(rect)
NSMaxY(rect)
NSEqualRects(rect1, rect2)
NSEqualSizes(size1, size2)
NSEqualPoints(point1, point2)
NSEdgeInsetsEqual(insets2, insets2)
NSIsEmptyRect(rect)
NSIntegralRect(rect)
NSInsetRect(rect, 10, 5)
NSOffsetRect(rect, -2, 8.3)
NSUnionRect(rect1, rect2)
NSIntersectionRect(rect1, rect2)
NSContainsRect(rect1, rect2)
NSPointInRect(rect, point)
NSIntersectsRect(rect1, rect2)

// good
rect.width
rect.height
rect.minX
rect.midX
rect.maxX
rect.minY
rect.midY
rect.maxY
rect.isEmpty
rect.integral
rect.insetBy(dx: 5.0, dy: -7.0)
rect.offsetBy(dx: 5.0, dy: -7.0)
rect1.union(rect2)
rect1.intersect(rect2)
rect1.contains(rect2)
rect.contains(point)
rect1.intersects(rect2)


Line Length

1行にはあまりにも多くの文字を含めるべきではありません。

https://github.com/realm/SwiftLint/blob/master/Rules.md#line-length


Mark

MARK コメントは有効な形式であるべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#mark

// bad

//MARK: bad
// MARK:bad
// MARK: -bad
// MARK:- bad
// MARK bad

// good
// MARK: good
// MARK: - good
// MARK: -


Multiple Closures with Trailing Closure

複数のクロージャを引数とする場合、トレイリングクロージャを使うべきではありません。

https://github.com/realm/SwiftLint/blob/master/Rules.md#multiple-closures-with-trailing-closure

// bad

foo.something(param1: { $0 }) { $0 + 1 }

// good
foo.something(param1: { $0 }, param2: { $0 + 1 })


Nesting

型は最大1レベル、ステートメントは最大5レベルの深さでネストすべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#nesting

// bad

class A { class B { class C { } } }

// good
class A { class B { } }


No Fallthrough Only

case に少なくとも1つのステートメントが含まれている場合のみ、fallthrouth を使うべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#no-fallthrough-only

// bad

switch myvar {
case 1:
fallthrough
case 2:
var a = 2
}

// good
switch myvar {
case 1:
var a = 1
fallthrough
case 2:
var a = 2
}
switch myvar {
case 1, 2:
var a = 2
}


Notification Center Detachment

オブジェクトは deinit でのみ自分自身のオブザーバを削除すべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#notification-center-detachment

// bad

class Foo {
func bar() {
NotificationCenter.default.removeObserver(self)
}
}

// good
class Foo {
deinit {
NotificationCenter.default.removeObserver(self)
}
}


Opening Brace Spacing

{ は定義と同じ行で前に1つの半角スペースを置くべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#opening-brace-spacing

// bad

func abc(){
}
func abc()
{
}

// good
func abc() {
}


Operator Function Whitespace

演算子の定義時、1つの半角スペースで囲まれるべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#operator-function-whitespace

// bad

func <|(lhs: Int, rhs: Int) -> Int { }
func <| (lhs: Int, rhs: Int) -> Int { }

// good
func <| (lhs: Int, rhs: Int) -> Int { }


Private over fileprivate

fileprivate より private を使うべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#private-over-fileprivate

// TODO: 例を見ても法則がわからない。。


Private Unit Test

private の単体テストは暗黙のうちにスキップされます。

https://github.com/realm/SwiftLint/blob/master/Rules.md#private-unit-test

// bad

private class FooTests: XCTestCase {
func test1() { }
}

class FooTests: XCTestCase {
// bad
private func test1() { }

// good
func test1() { }
}


Protocol Property Accessors Order

プロトコルでプロパティを定義するときは、アクセサの順番を「ゲッター→セッター」とすべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#prohibited-calls-to-super

protocol Foo {

// bad
var bar: String { set get }

// good
var bar: String { set }
var bar: String { get }
var bar: String { get set }
}


Redundant Discardable Let

関数の戻り値を使わずに実行する場合、 let _ = foo() より _ = foo() を使うべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#redundant-discardable-let

// bad

let _ = foo()
if let _ = foo() { }
guard let _ = foo() else { return }

// good
_ = foo()


Redundant @objc Attribute

冗長な @objc 属性は避けるべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#redundant-objc-attribute

// bad

@objc @IBAction private func foo(_ sender: Any) { }

// good
@IBAction private func foo(_ sender: Any) { }


Redundant Optional Initialization

オプショナル型の変数を nil で初期化するのは冗長です。

https://github.com/realm/SwiftLint/blob/master/Rules.md#redundant-optional-initialization

// bad

var myVar: Int? = nil

// good
var myVar: Int?
let myVar: Int? = nil
var myVar: Int? = 0


Redundant Set Access Control Rule

プロパティのセッターのアクセスレベルは、変数のアクセスレベルと同様であれば明示的に指定すべきではありません。

https://github.com/realm/SwiftLint/blob/master/Rules.md#redundant-set-access-control-rule

// bad

private(set) private var foo: Int

// good
private(set) public var foo: Int


Redundant String Enum Value

文字列の列挙型の値は、ケースと同名なら省略できます。

https://github.com/realm/SwiftLint/blob/master/Rules.md#redundant-string-enum-value

// bad

enum Numbers: String {
case one = "one"
case two = "two"
}

// good
enum Numbers: String {
case one
case two
}
enum Numbers: String {
case one = "ONE"
case two = "TWO"
}


Redundant Void Return

関数の定義で Void を返すのは冗長です。

https://github.com/realm/SwiftLint/blob/master/Rules.md#redundant-void-return

// bad

func foo() -> Void { }
func foo() -> () { }

// good
func foo() { }
let foo: Int -> Void


Returning Whitespace

戻り値の矢印と型は1つの半角スペースまたは別の行で区切るべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#returning-whitespace

// bad

func abc()-> Int { }
func abc() ->Int { }
func abc()->Int { }

// good
func abc() -> Int { }
func abc()
-> Int { }
func abc() ->
Int { }


Shorthand Operator

省略形の演算子を使うべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#shorthand-operator

// bad

foo = foo + 1
foo = foo - 1
foo = foo * 1
foo = foo / 1

// good
foo += 1
foo -= 1
foo *= 1
foo /= 1


Statement Position

elsecatch は、前の定義の1つの半角スペースの後ろで同じ行にあるべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#statement-position

// bad

}else {

}
catch {

// good
} else {

} catch {


Superfluous Disable Command

無効化されたルールが無効化された領域で違反を起こさなかった場合、SwiftLintの disable コマンドは不要です。

https://github.com/realm/SwiftLint/blob/master/Rules.md#superfluous-disable-command


Switch and Case Statement Alignment

case 文はそれを囲む switch 文と同じインデントにすべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#switch-and-case-statement-alignment

// bad

switch someBool {
case true:
print("red")
case false:
print("blue")
}

// good
switch someBool {
case true:
print("red")
case false:
print("blue")
}


Syntactic Sugar

糖衣構文を使うべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#syntactic-sugar

// bad

let x: Array<String>
let x: Dictionary<Int, String>
let x: Optional<Int>
let x: ImplicitlyUnwrappedOptional<Int>

// good
let x: [String]
let x: [Int: String]
let x: Int?
let x: Int!


Todo

TODOFIXME は解決すべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#todo

// bad

// TODO:
// FIXME:


Trailing Comma

配列やディクショナリの末尾のカンマは避けるべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#trailing-comma

// bad

let array = [1, 2, 3,]
let dictionary = ["foo": 1, "bar": 2,]

// good
let array = [1, 2, 3]
let dictionary = ["foo": 1, "bar": 2]


Trailing Newline

ファイルは末尾に1つの改行を持つべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#trailing-newline


Trailing Semicolon

行の末尾にセミコロンを付けるべきではありません。

https://github.com/realm/SwiftLint/blob/master/Rules.md#trailing-semicolon

// bad

let a = 0;

// good
let a = 0


Trailing Whitespace

行の末尾に半角スペースを付けるべきではありません。

https://github.com/realm/SwiftLint/blob/master/Rules.md#trailing-whitespace

// bad

let a = 1

// good
let a = 1


Type Body Length

型内はあまりにも多くの行にまたがるべきではないです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#type-body-length


Type Name

型名は英数のみを含み、大文字で始まり、3〜40文字にすべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#type-name

// bad

class My_Type { }
class myType { }
class aa { }

// good
class MyType { }


Unneeded Break in Switch

不要な break は避けるべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#unneeded-break-in-switch

switch a {

// bad
case .foo:
something()
break

// good
case .bar:
something()
case .baz:
break
case .qux:
for i in [0, 1, 2] { break }
}


Unused Closure Parameter

クロージャで使われていないパラメータは _ に置き換えるべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#unused-closure-parameter

// bad

[1, 2].map { number in
3
}

// good
[1, 2].map { _ in
3
}
[1, 2].map { number in
number + 1
}
[1, 2].map { $0 + 1 }


Unused Control Flow Label

未使用の制御フローラベルは削除すべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#unused-control-flow-label

// bad

loop: while true { break }

// good
loop: while true { break loop }
loop: while true { continue loop }


Unused Enumerated

インデックスまたはアイテムが使われていない場合、 .enumerated() を削除できます。

https://github.com/realm/SwiftLint/blob/master/Rules.md#unused-enumerated

// TODO: わからない。。


Unused Optional Binding

let _ = より != nil を使うべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#unused-optional-binding

// bad

if let _ = a { }

// good
if a != nil { }


Unused Setter Value

セッターの値は使われるべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#unused-setter-value

var aValue: String {

get {
return Persister.shared.aValue
}
set {
// bad
Persister.shared.aValue = aValue
// good
Persister.shared.aValue = newValue
}
// bad
set { }
}


Valid IBInspectable

@IBInspectable はサポートされている型の変数のみに使い、その型を明示的にすべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#valid-ibinspectable

class Foo {

// bad
@IBInspectable private let count: Int
@IBInspectable private var count = 0
@IBInspectable private var count: Int?
@IBInspectable private var count: Int!

// good
@IBInspectable private var count: Int
@IBInspectable private var count: Int = 0
}


Vertical Parameter Alignment

関数の定義時、パラメータが複数行にまたがっている場合は垂直方向に揃えるべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#vertical-parameter-alignment

// bad

func validateFunction(_ file: File, kind: SwiftDeclarationKind,
dictionary: [String: SourceKitRepresentable]) { }
func validateFunction(_ file: File, kind: SwiftDeclarationKind,
dictionary: [String: SourceKitRepresentable]) { }

// good
func validateFunction(_ file: File, kind: SwiftDeclarationKind,
dictionary: [String: SourceKitRepresentable]) { }


Vertical Whitespace

空白行は1行に制限します。

https://github.com/realm/SwiftLint/blob/master/Rules.md#vertical-whitespace


Void Return

-> () より -> Void を使うべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#void-return

// bad

let abc: () -> Void = { }

// good
let abc: () -> () = { }


Weak Computed Property

コンピューテッドプロパティに weak を追加しても効果はありません。

https://github.com/realm/SwiftLint/blob/master/Rules.md#weak-computed-property

class Foo {

private weak var _delegate: SomeProtocol?

// bad
weak var delegate: SomeProtocol? {
// good
var delegate: SomeProtocol? {
get { return _delegate }
set { _delegate = newValue }
}
}


Weak Delegate

デリゲートは循環参照を避けるために弱参照とすべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#weak-delegate

class Foo {

// bad
var delegate: SomeProtocol?

// good
weak var delegate: SomeProtocol?
}


XCTFail Message

XCTFail の呼び出しにはアサーションの説明を含めるべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#xctfail-message

func testFoo() {

// bad
XCTFail()

// good
XCTFail("bar")
}


Opt-in

デフォルトで無効になっているルールの一覧です。


AnyObject Protocol

クラス専用のプロトコルでは、 class より AnyObject を使うべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#anyobject-protocol

// bad

protocol SomeClassOnlyProtocol: class { }

// good
protocol SomeClassOnlyProtocol: AnyObject { }


Array Init

シーケンスを配列に変換する場合、 seq.map { $0 } より Array(seq) を使うべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#array-init

// bad

seq.map { $0 }

// good
Array(seq)


Attributes

属性は関数や型では別の行にあるべきですが、変数やインポートでは同じ行にあるべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#attributes

// bad

@available(iOS 9.0, *) func animate(view: UIStackView)

@available(iOS 9.0, *) class UIStackView

@objc
var x: String

@testable
import SourceKittenFramework

// good
@available(iOS 9.0, *)
func animate(view: UIStackView)

@available(iOS 9.0, *)
class UIStackView

@objc var x: String

@testable import SourceKittenFramework


Closure Body Length

クロージャ内はあまりにも多くの行にまたがるべきではないです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#closure-body-length

// bad

foo.bar { toto in
let a = 0
let a = 0
let a = 0
let a = 0
let a = 0
let a = 0
let a = 0
let a = 0
let a = 0
let a = 0
let a = 0
let a = 0
let a = 0
let a = 0
let a = 0
let a = 0
let a = 0
let a = 0
let a = 0
let a = 0
let a = 0
}

// good
foo.bar { $0 }
foo.bar { toto in
}


Closure End Indentation

クロージャの終了は開始と同様のインデントを持つべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#closure-end-indentation

// bad

SignalProducer(values: [1, 2, 3])
.startWithNext { number in
print(number)
}

// good
SignalProducer(values: [1, 2, 3])
.startWithNext { number in
print(number)
}
[1, 2].map { $0 + 1 }


Closure Spacing

クロージャ内は各括弧の内側に1つの半角スペースがあるべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#closure-spacing

// bad

[].filter {$0.contains(location)}

// good
[].filter { $0.contains(location) }


Collection Element Alignment

コレクション内の全要素は垂直方向に揃うべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#collection-element-alignment

// bad

let abc = [
"alpha": "a",
"beta": "b",
"gamma": "g",
"delta": "d",
"epsilon": "e"
]

// good
let abc = [
"alpha": "a",
"beta": "b",
"gamma": "g",
"delta": "d",
"epsilon": "e"
]

let abc = [1, 2, 3, 4]

let abc = [
1, 2, 3, 4
]


Conditional Returns on Newline

条件文では次の行でリターンすべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#conditional-returns-on-newline

// bad

guard true else { return }

// good
guard true else {
return true
}


Contains over first not nil

first(where:) != nil より contains を使うべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#contains-over-first-not-nil

// bad

myList.first { $0 % 2 == 0 } != nil
myList.first(where: { $0 % 2 == 0 }) != nil

// good
myList.first { $0 % 2 == 0 }
myList.first(where: { $0 % 2 == 0 })


Convenience Type

静的メンバーのみをホストするために使われる型は、インスタンス化を回避するために、case のない列挙型として実装すべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#convenience-type

// bad

struct Math {
public static let pi = 3.14
}
class Math {
public static let pi = 3.14
}

// good
enum Math {
public static let pi = 3.14
}

// 継承を伴う場合はOK
class MathViewController: UIViewController {
public static let pi = 3.14
}

// Obj-Cに見えるクラスはOK
@objc class Math: NSObject {
public static let pi = 3.14
}

// 静的でない型もある場合はOK
struct Math {
public static let pi = 3.14
public let randomNumber = 2
}


Discouraged Object Literal

オブジェクトリテラルよりイニシャライザを使うべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#discouraged-object-literal

// bad

let image = #imageLiteral(resourceName: "image.jpg")
let color = #colorLiteral(red: value, green: value, blue: value, alpha: 1)

// good
let image = UIImage(named: "image")
let color = UIColor(red: value, green: value, blue: value, alpha: 1)


Discouraged Optional Boolean

オプショナル型よりそうでない Bool 型を使うべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#discouraged-optional-boolean

// bad

var foo: Bool?

// good
var foo: Bool


Discouraged Optional Collection

オプショナルのコレクションより空のコレクションを使うべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#discouraged-optional-collection

// bad

var foo: [Int]?
var foo: [String: Int]?
let foo: [Int]? = nil
let foo: [String: Int]? = nil

// good
var foo: [Int]
var foo: [String: Int]
let foo: [Int] = []
let foo: [String: Int] = [:]


Empty Count

count0 と比較するより isEmpty を使うべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#empty-count

// bad

[Int]().count == 0
[Int]().count > 0
[Int]().count != 0

// good
[Int]().isEmpty


Empty String

空の文字列と比較するより isEmpty を使うべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#empty-string

// bad

myString == ""
myString != ""

// good
myString.isEmpty
!myString.isEmpty


Empty XCTest Method

空のXCTestメソッドを実装すべきではありません。

https://github.com/realm/SwiftLint/blob/master/Rules.md#empty-xctest-method

// bad

class TotoTests: XCTestCase {

override func setUp() {
}

override func tearDown() {
}

func testFoo() {
}

}

// good
class TotoTests: XCTestCase {

var foobar: Foobar?

override func setUp() {
super.setUp()
foobar = Foobar()
}

override func tearDown() {
foobar = nil
super.tearDown()
}

func testFoo() {
XCTAssertTrue(foobar?.foo)
}

func helperFunction() {
}
}


Explicit ACL

全ての定義はアクセス制御レベルのキーワードを明示的に指定すべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#explicit-acl

// bad

enum A { }

// good
internal enum A { }


Explicit Enum Raw Value

列挙型はローバリューを明示的に割り当てるべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#explicit-enum-raw-value

// bad

enum Numbers: Int {
case one
case two
}

// good
enum Numbers: Int {
case one = 1
case two = 2
}


Explicit Init

.init() を明示的に呼び出すべきではありません。

https://github.com/realm/SwiftLint/blob/master/Rules.md#explicit-init

// bad

[1].flatMap { String.init($0) }
[String.self].map { Type in Type.init(1) }

// good
[1].flatMap(String.init)
[String.self].map { $0.init(1) }
[String.self].map { type in type.init(1) }


Explicit Self

インスタンス変数と関数は self. で明示的にアクセスされるべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#explicit-self

struct A {

let p1: Int
func f1() { }
func f2() {
// bad
f1()
_ = p1

// good
self.f1()
_ = self.p1
}
}


Explicit Top Level ACL

最上位の定義はアクセス制御レベルを明示的に指定すべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#explicit-top-level-acl

// bad

enum A {
enum B { }
}

// good
internal enum A {
enum B { }
}


Explicit Type Interface

プロパティは型インターフェースを持つべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#explicit-type-interface

class Foo {

// bad
var myVar = 0

// good
var myVar: Int? = 0
}


Extension Access Modifier

エクステンションにはアクセス修飾子を使うべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#explicit-type-interface

// TODO: 例を見ても法則がわからない。。


Fallthrough

fallthrough は使うべきではありません。

https://github.com/realm/SwiftLint/blob/master/Rules.md#fallthrough

// bad

switch foo {
case .bar:
fallthrough
case .bar2:
something()
}

// good
switch foo {
case .bar, .bar2:
something()
}


Fatal Error Message

fatalError はメッセージを付けて呼び出すべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#fatal-error-message

// bad

func foo() {
fatalError()
}

// good
func foo() {
fatalError("Foo")
}


File Header

https://github.com/realm/SwiftLint/blob/master/Rules.md#file-header

// TODO: 例を見ても法則がわからない。。


File Name

ファイル名はファイル内で定義されている型またはエクステンションと一致すべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#file-name


First Where

コレクションでは .filter {} .first より .first(where:) を使うべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#first-where

// bad

myList.filter { $0 % 2 == 0 } .first

// good
myList.first(where: { $0 % 2 == 0 })
myList.first { $0 % 2 == 0 }


Force Unwrapping

強制アンラップ( ! )は使うべきではありません。

https://github.com/realm/SwiftLint/blob/master/Rules.md#force-unwrapping

// bad

let url = NSURL(string: query)!

// good
if let url = NSURL(string: query) { }


Function Default Parameter at End

関数でデフォルト値を持つ引数は後ろにまとめるべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#function-default-parameter-at-end

// bad

func foo(y: Int = 0, x: String, z: CGFloat = 0) { }

// good
func foo(x: String, y: Int = 0, z: CGFloat = 0) { }


Identical Operands

同一のオペランドを比較するのはおそらく間違いです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#identical-operands

// bad

foo == foo

// good
foo == bar


Implicit Return

クロージャでは暗黙のリターンを優先すべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#implicit-return

// bad

foo.map {
return $0 + 1
}

// good
foo.map { $0 + 1 }


Implicitly Unwrapped Optional

暗黙的にアンラップされるオプショナル型はできる限り使うべきではありません。

https://github.com/realm/SwiftLint/blob/master/Rules.md#implicitly-unwrapped-optional

// bad

private var label: UILabel!
let int: Int! = 42

// good
@IBOutlet private var label: UILabel!
let int: Int? = 42


Joined Default Parameter

デフォルトの区切り文字は明示的に使うべきではありません。

https://github.com/realm/SwiftLint/blob/master/Rules.md#joined-default-parameter

// bad

let foo = bar.joined(separator: "")

// good
let foo = bar.joined()
let foo = bar.joined(separator: ",")


Last Where

コレクションでは .filter {} .last より .last(where:) を使うべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#last-where

// bad

myList.filter { $0 % 2 == 0 } .last

// good
myList.last(where: { $0 % 2 == 0 })


Legacy Random

従来の関数より type.ramdom(in:) を使うべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#legacy-random

// bad

arc4random(10)
arc4random_uniform(83)
drand48(52)

// good
Int.random(in: 0..<10)
Double.random(in: 8.6...111.34)
Float.random(in: 0..<1)


Variable Declaration Whitespace

letvar は他のステートメントと空白行で区切るべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#variable-declaration-whitespace

// bad

let a = 0
var x = 1
x = 2

// good
let a = 0
var x = 1

x = 2


Literal Expression End Indentation

配列とディクショナリのリテラルの末尾は、開始行と同様のインデントを持つべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#literal-expression-end-indentation

// bad

let x = [
1,
2
]

// good
[1, 2, 3]
let x = [
1,
2
]
let x = [1,
2
]
let x = [
1,
2]


Lower ACL than parent

定義が親よりも低いまたは同じアクセス制御レベルを持つようにすべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#lower-acl-than-parent

// bad

struct Foo {
public func bar() { }
}

// good
public struct Foo {
public func bar() { }
}


Missing Docs

定義はドキュメント化すべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#missing-docs

// good

/// docs
public class A {
/// docs
public func b() { }
}
/// docs
public class B: A {
// オーバーライドメソッドはOK
override public func b() { }
}


Modifier Order

修飾子の順番は一貫しているべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#modifier-order

public class Foo {

// bad
convenience required public init() { }
static public let bar = 42

// good
public convenience required init() { }
public static let bar = 42
}


Multiline Arguments

引数は同じ行に入れるか1行に1つずつ入れるべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#multiline-arguments

// bad

func foo(
param1: "Param1", param2: "Param2",
param3: "Param3"
)

// good
func foo(param1: "Param1", param2: "Param2", param3: "Param3")
func foo(
param1: "Param1",
param2: "Param2",
param3: "Param3"
)


Multiline Arguments Brackets

複数行の引数は、それらを括る大括弧を新しい行に持つべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#multiline-arguments-brackets

// bad

foo(param1: "Param1",
param2: "Param2"
)
foo(
param1: "Param1",
param2: "Param2")

// good
foo(param1: "Param1", param2: "Param2")
foo(
param1: "Param1",
param2: "Param2"
)


Multiline Function Chains

関数を連鎖的に呼び出す場合、同じ行に入れるか1行に1つずつ入れるべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#multiline-function-chains

// bad

let evenSquaresSum = [20, 17, 35, 4]
.filter { $0 % 2 == 0 } .map { $0 * $0 }
.reduce(0, +)

// good
let evenSquaresSum = [20, 17, 35, 4].filter { $0 % 2 == 0 } .map { $0 * $0 } .reduce(0, +)
let evenSquaresSum = [20, 17, 35, 4]
.filter { $0 % 2 == 0 }
.map { $0 * $0 }
.reduce(0, +)


Multiline Literal Brackets

複数行のリテラルは、新しい行にそれを括る大括弧を入れるべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#multiline-literal-brackets

// bad

let trio = ["harry",
"ronald",
"hermione"
]
let trio = [
"harry",
"ronald",
"hermione"]

// good
let trio = ["harry", "ronald", "hermione"]
let trio = [
"harry",
"ronald",
"hermione"
]


Multiline Parameters

関数とメソッドの引数は、同様の行にあるか1行に1つずつあるべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#multiline-parameters

// bad

func foo(param1: Int, param2: Bool,
param3: [String]) { }

// good
func foo(param1: Int, param2: Bool, param3: [String]) { }
func foo(param1: Int,
param2: Bool,
param3: [String]) { }


Multiline Parameters Brackets

複数行の引数は、新しい行にそれを括る大括弧を入れるべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#multiline-parameters-brackets

// bad

func foo(param1: "Param1",
param2: "Param2",
param3: "Param3"
)
func foo(
param1: "Param1",
param2: "Param2",
param3: "Param3")

// good
func foo(param1: "Param1", param2: "Param2", param3: "Param3")
func foo(
param1: "Param1",
param2: "Param2",
param3: "Param3"
)


Nimble Operator

フリーのmatcher関数よりNimble演算子のオーバーロードを使うべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#nimble-operator

//bad

expect(seagull.squawk).to(equal("Hi"))
expect(seagull.squawk).toNot(equal("Hi"))
expect(10).to(beGreaterThan(2))

// good
expect(seagull.squawk) == "Hi!"
expect(seagull.squawk) != "Hi!"
expect(10) > 2


No Extension Access Modifier

エクステンションにアクセス修飾子を付けるべきではありません。

https://github.com/realm/SwiftLint/blob/master/Rules.md#no-extension-access-modifier

// bad

private extension String { }
fileprivate extension String { }
internal extension String { }
public extension String { }
open extension String { }

// good
extension String { }


No Grouping Extension

エクステンションは同じソースファイル内のコードをグループ化するために使うべきではありません。

https://github.com/realm/SwiftLint/blob/master/Rules.md#no-grouping-extension

// bad

enum Fruit { }
extension Fruit { }

// good
// プロトコルのデフォルト実装はOK
protocol Food { }
extension Food { }


NSLocalizedString Key

genstringsが機能するためには、静的文字列を NSLocalizedString のキーとして使うべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#nslocalizedstring-key

// bad

NSLocalizedString(method(), comment: nil)

// good
NSLocalizedString("key", comment: nil)


Number Separator

_ は十進数で千の区切り文字として使うべきです。

// bad

let foo = 1000
let foo = 1000_000.000_000_1
let foo = 1_000_000.000000_1
let foo = 1_0_00_000.000_000_1

// good
let foo = 1_000
let foo = 1_000_000.000_000_1


Object Literal

画像や色はイニシャライザよりリテラルを使って生成すべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#object-literal

// bad

let image = UIImage(named: "image")
let color = UIColor(red: 0.9607843161, green: 0.7058823705, blue: 0.200000003, alpha: 1.0)

// good
let image = #imageLiteral(resourceName: "image.jpg")
let color = #colorLiteral(red: 0.9607843161, green: 0.7058823705, blue: 0.200000003, alpha: 1.0)


Operator Usage Whitespace

演算子を使うときは1つの半角スペースで囲まれるべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#operator-usage-whitespace

// bad

let foo = 1+2
let foo=1+2

// good
let foo = 1 + 2


Overridden methods call super

一部のオーバーライドメソッドは常に親クラスのメソッドを呼び出すべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#overridden-methods-call-super

// bad

class VC: UIViewController {
override func viewWillAppear(_ animated: Bool) {
}
}

// good
class VC: UIViewController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}
override func loadView() {
}
}


Override in Extension

エクステンションでは定義をオーバーライドすべきではありません。

https://github.com/realm/SwiftLint/blob/master/Rules.md#override-in-extension

extension Person {

// good
var age: Int { return 42 }
func celebrateBirthday() { }

// bad
override var age: Int { return 42 }
override func celebrateBirthday() { }
}


Pattern Matching Keywords

キーワードをタプルの外に出し、複数のパターンマッチングバインディングを組み合わせるべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#pattern-matching-keywords

switch foo {

// bad
case (let x, let y):

// good
case let (x, y):
}


Prefixed Top-Level Constant

最上位の定数はプリフィックスに k を付けるべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#prefixed-top-level-constant

// bad

let bar = 20.0

// good
let kBar = 20.0
struct Foo {
let bar = 20.0
}


Private Actions

@IBActionprivate にすべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#private-actions

// bad

class Foo {
@IBAction func barButtonTapped(_ sender: UIButton) { }
}

// good
class Foo {
@IBAction private func barButtonTapped(_ sender: UIButton) { }
}


Private Outlets

@IBOutletprivate にすべきです。

∵上位レイヤーへ UIKit が漏洩するのを防ぐため

https://github.com/realm/SwiftLint/blob/master/Rules.md#private-outlets

// bad

class Foo {
@IBOutlet var label: UILabel?
}

// good
class Foo {
@IBOutlet private var label: UILabel?
}


Prohibited Interface Builder

IBを使ってビューを生成するのは避けるべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#prohibited-interface-builder

class ViewController: UIViewController {

// bad
@IBOutlet var label: UILabel!
@IBAction func buttonTapped(_ sender: UIButton) { }

// good
var label: UILabel!
@objc func buttonTapped(_ sender: UIButton) { }
}


Prohibited calls to super

一部のメソッドは親クラスのメソッドを呼び出してはいけません。

https://github.com/realm/SwiftLint/blob/master/Rules.md#prohibited-calls-to-super

// bad

class VC: UIViewController {
override func loadView() {
super.loadView()
}
}


Quick Discouraged Call

describecontext 内で処理を呼び出すべきではありません。

https://github.com/realm/SwiftLint/blob/master/Rules.md#quick-discouraged-call

class TotoTests: QuickSpec {

override func spec() {
describe("foo") {
// bad
let foo = Foo()
context("foo") {
// bad
foo.bar()
it("does something") {
// good
let foo = Foo()
foo.bar()
}
}
}
}
}


Quick Discouraged Focused Test

一部のみ有効となるテストは実行すべきではありません。

https://github.com/realm/SwiftLint/blob/master/Rules.md#quick-discouraged-focused-test

class TotoTests: QuickSpec {

override func spec() {
// bad
fdescribe("foo") { }
fcontext("foo") { }
fit("foo") { }
fitBehavesLike("foo")

// good
describe("foo") { }
context("foo") { }
it("foo") { }
itBehavesLike("foo")
}
}


Quick Discouraged Pending Test

一部のみ無効となるテストは実行すべきではありません。

https://github.com/realm/SwiftLint/blob/master/Rules.md#quick-discouraged-pending-test

class TotoTests: QuickSpec {

override func spec() {
// bad
xdescribe("foo") { }
xcontext("foo") { }
xit("foo") { }
pending("foo")
xitBehavesLike("foo")

// good
describe("foo") { }
context("foo") { }
it("foo") { }
itBehavesLike("foo")
}
}


Redundant Nil Coalescing

?? 演算子は左辺が nil の場合のみ評価されるため、右辺に nil を記述するのは冗長です。

https://github.com/realm/SwiftLint/blob/master/Rules.md#redundant-nil-coalescing

// bad

var myVar: Int? = nil
myVar ?? nil

// good
var myVar: Int?
myVar ?? 0


Redundant Type Annotation

変数は冗長な型アノテーションを持つべきではありません。

https://github.com/realm/SwiftLint/blob/master/Rules.md#redundant-type-annotation

// bad

var url: URL = URL()

// good
var url = URL()
var url: CustomStringConvertible = URL()


Required Deinit

クラスは明示的な deinit メソッドを持つべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#required-deinit

// bad

class Apple { }

// good
class Apple {
deinit { }
}


Required Enum Case

特定のプロトコルに準拠した列挙型は特定のケースを実装する必要があります。

https://github.com/realm/SwiftLint/blob/master/Rules.md#required-enum-case

// bad

enum MyNetworkResponse: String, NetworkResponsable {
case success
case error
}

// good
enum MyNetworkResponse: String, NetworkResponsable {
case success
case error
case notConnected
}
enum MyNetworkResponse: String, NetworkResponsable {
case success
case error
case notConnected(error: Error)
}


Single Test Class

テストファイルは単一の QuickSpec または XCTestCase クラスを含むべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#single-test-class

// bad

class FooTests: QuickSpec { }
class BarTests: QuickSpec { }

class FooTests: XCTestCase { }
class BarTests: XCTestCase { }

class FooTests: XCTestCase { }
class BarTests: QuickSpec { }

// good
class FooTests: XCTestCase { }

class FooTests: QuickSpec { }


Min or Max over Sorted First or Last

sorted().firstsorted().last より min()max() を使うべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#min-or-max-over-sorted-first-or-last

// bad

myList.sorted().first
myList.sorted().last
let min = myList.sorted(by: >).first

// good
myList.min()
myList.max()
let min = myList.min(by: >)


Sorted Imports

インポート文はソートされるべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#sorted-imports

// bad

import AAA
import CCC
import BBB
import DDD

// good
import AAA
import BBB
import CCC
import DDD


Static Operator

演算子は自由関数でなく静的関数として定義すべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#static-operator

// bad

func == (lhs: A, rhs: A) -> Bool {
return false
}
func == <T>(lhs: A<T>, rhs: A<T>) -> Bool {
return false
}

// good
class A: Equatable {
static func == (lhs: A, rhs: A) -> Bool {
return false
}
}
class A<T>: Equatable {
static func == <T>(lhs: A<T>, rhs: A<T>) -> Bool {
return false
}
}


Strict fileprivate

fileprivate は避けるべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#strict-fileprivate

// bad

fileprivate extension String { }

extension String {
fileprivate func Something() { }
}

// good
private extension String { }

extension String {
func Something() { }
}


Strong IBOutlet

@IBOutlet は弱参照で定義すべきではありません。

https://github.com/realm/SwiftLint/blob/master/Rules.md#strong-iboutlet

// bad

class ViewController: UIViewController {
@IBOutlet weak var label: UILabel?
@IBOutlet unowned var label: UILabel!
}

// good
class ViewController: UIViewController {
@IBOutlet var label: UILabel?
weak var label: UILabel!
}


Switch Case on Newline

switch 文の中の case 文は常に改行すべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#switch-case-on-newline

// bad

switch foo {
case 1: return true
}

// good
switch foo {
case 1:
return true
}


Toggle Bool

someBool = !someBool より someBool.toggle() を使うべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#toggle-bool

// bad

isHidden = !isHidden

// good
isHidden.toggle()


Trailing Closure

できる限りトレイリングクロージャを使うべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#trailing-closure

// bad

foo.map({ $0 + 1 })
foo.reduce(0, combine: { $0 + 1 })

// good
foo.map { $0 + 1 }
foo.reduce(0) { $0 + 1 }


Unavailable Function

未実装の関数は使用不可としてマークされるべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#unavailable-function

// bad

class ViewController: UIViewController {
public required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

// good
class ViewController: UIViewController {
@available(*, unavailable)
public required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}


Unneeded Parentheses in Closure Argument

クロージャ引数の定義時に括弧は不要です。

https://github.com/realm/SwiftLint/blob/master/Rules.md#unneeded-parentheses-in-closure-argument

// bad

let foo = { (bar) in }
let foo = { (bar, _) in }

// good
let foo = { (bar: Int) in }
let foo = { bar in }
let foo = { bar, _ in }


Untyped Error in Catch

catch 文は型キャストなしでエラー変数を定義すべきではありません。

https://github.com/realm/SwiftLint/blob/master/Rules.md#untyped-error-in-catch

// bad

do {
try foo()
} catch let error {
}

// good
do {
try foo()
} catch let error as MyError {
} catch { }


Unused Import

インポートされた全てのモジュールがファイルをコンパイルするために必要とされるべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#unused-import

// bad

import Foundation
class A { }

// good
import Foundation
@objc
class A { }


Unused Private Declaration

private の定義はそのファイル内で参照されるべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#unused-private-declaration

// bad

private let a = 0

// good
private let a = 0
_ = a


Vertical Parameter Alignment On Call

関数の呼び出し時、パラメータが複数行にまたがっている場合は垂直方向に揃えるべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#vertical-parameter-alignment-on-call

// bad

validateFunction(_ file: File, kind: SwiftDeclarationKind,
dictionary: [String: SourceKitRepresentable]) { }
validateFunction(_ file: File, kind: SwiftDeclarationKind,
dictionary: [String: SourceKitRepresentable]) { }

// good
validateFunction(_ file: File, kind: SwiftDeclarationKind,
dictionary: [String: SourceKitRepresentable]) { }


Vertical Whitespace Between Cases

SwitchのCase間は空白行を1行含んでください。

https://github.com/realm/SwiftLint/blob/master/Rules.md#vertical-whitespace-between-cases

// bad

switch x {
case .valid:
print("x is valid")
case .invalid:
print("x is invalid")
}

// good
switch x {
case .valid:
print("x is valid")

case .invalid:
print("x is invalid")
}


Vertical Whitespace before Closing Braces

中括弧を閉じる前に空白行を入れないでください。

https://github.com/realm/SwiftLint/blob/master/Rules.md#vertical-whitespace-before-closing-braces

// bad

{
{
}

}

// good
{
{
}
}


Vertical Whitespace after Opening Braces

中括弧を開いた後に空白行を入れないでください。

https://github.com/realm/SwiftLint/blob/master/Rules.md#vertical-whitespace-after-opening-braces

// bad

{

{
}
}

// good
{
{
}
}


XCTest Specific Matcher

XCTAssertEqualXCTAssertNotEqual より特定のXCTestマッチャーを使うべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#xctest-specific-matcher

// bad

XCTAssertEqual(foo, true)
XCTAssertEqual(foo, false)
XCTAssertEqual(foo, nil)
XCTAssertNotEqual(foo, true)
XCTAssertNotEqual(foo, false)
XCTAssertNotEqual(foo, nil)

// good
XCTAssertFalse(foo)
XCTAssertTrue(foo)
XCTAssertNil(foo)
XCTAssertNotNil(foo)
XCTAssertEqual(foo, 2)


Yoda condition rule

変数は比較演算子の左側、定数は右側に配置すべきです。

https://github.com/realm/SwiftLint/blob/master/Rules.md#yoda-condition-rule

// bad

if 42 == foo { }

// good
if foo == 42 { }


おわりに

SwiftLintのルールを一通り眺めるだけでもSwiftyに書けるようになった気がします。

ただ、これらを他のメンバーにも守ってもらうには、やはりSwiftLintの導入が便利です。