Swift3 全予約語 (98語) の解説

Swift3 に合わせて [Swift2 全予約語 (82語) の解説](http://qiita.com/ezura/items/610caef024cb5f956db7) をまとめ直しました。

Swift4 はこちら [Swift4 全予約語 (98語) の解説](https://qiita.com/ezura/items/d011c9b13c70055b6e57)

## 宣言 (declarations)
クラス、変数、定数、メソッド、関数などの宣言部分で使用する予約語

### class  
クラスの宣言や、メソッドやプロパティの前に指定することでクラスメソッド、クラスプロパティの宣言をします。

```swift
class Sample {
    var member = 1
}

let a = Sample()
let b = a
a === b       // -> true (指すものは同じ)
a.member = 2
b.member      // -> 2
```

プロトコルで、適用先をクラスだけに制限したいときにも使います。

```swift
protocol SampleProtocol : class {
    
}

class Sample : SampleProtocol {
    
}
```

### deinit  
デストラクタの宣言をします。これは class でのみ有効です。
スーパークラスの deinit はサブクラスの deinit 実行後に自動的に呼ばれます。

```swift
class SuperClass {
    deinit { print("Super Class's deinit is called") }
}

class SubClass: SuperClass {
    deinit { print("Sub Class's deinit is called") }
}

var subClass: SubClass? = SubClass()
subClass = nil
```

```text:出力
Sub Class's deinit is called
Super Class's deinit is called
```

### enum  
列挙型の宣言をします。

### extension
定義済みのクラス、構造体、プロトコル、列挙型に対して振る舞いを追加します。

### fileprivate
アクセス修飾子の一種です。(Swift2 での private)
同じファイル内からのアクセスが可能です。

関連: [public](#public), [private](#private), [internal](#internal), [open](#open)
参考: [The Swift Programming Language (Swift 3) # Access Control](https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/AccessControl.html#//apple_ref/doc/uid/TP40014097-CH41-ID3)

### func  
メソッドまたは関数の宣言をします。

### import  
モジュールを読み込みます。

### init  
コンストラクタを宣言します。

### inout  
intout 指定された引数として渡された変数は、function 内での変更が適応されます。(表面的には参照渡しに似た動作になります)

具体的には下記の動作をします。

1. function の呼び出し時に、引数として与えられた値がコピーされ、そのコピーが function の中で使われます。
2. function の終了時に引数として与えられた変数にコピーが代入されます。

```swift
class SampleClass {}

func inoutSampleForClass(sampleClass: inout SampleClass?) {
    sampleClass = nil
}

func withoutInoutSampleForClass(var sampleClass: SampleClass?) {
    sampleClass = nil
}

var sampleClass: SampleClass? = SampleClass()

// inout なし
withoutInoutSampleForClass(sampleClass)
sampleClass  // => SampleClass のインスタンス

// inout あり
inoutSampleForClass(&sampleClass)
sampleClass  // => nil
```
   
```swift
func inoutSample(a: inout Int) {
    a = 100
}

func withoutInoutSample(var a: Int) {
    a = 100
}

var varInt = 1

// inout なし
withoutInoutSample(varInt)
varInt // => 1

// inout あり
inoutSample(&varInt)
varInt // => 100
```

参考: [In-Out Parameters](https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Declarations.html#//apple_ref/doc/uid/TP40014097-CH34-ID545)
 
### internal  
アクセス修飾子の一種です。
同じモジュール内からアクセスできます。
アクセス修飾子をつけなかった場合、デフォルトで `internal` となります。
関連: [public](#public), [private](#private), [open](#open), [fileprivate](#fileprivate)
参考: [The Swift Programming Language (Swift 3) # Access Control](https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/AccessControl.html#//apple_ref/doc/uid/TP40014097-CH41-ID3)

### let
定数を宣言します。
関連: [var](#var)

### open
アクセス修飾子の一種です。アクセス制限の種類の中で最もアクセス制限の緩い指定です。
外のモジュールからのアクセス、継承・オーバーライドが可能です。
性質上、この制限を指定できるのは class または オーバーライド可能な class member のみです。

[public](#public) との違いは、継承・オーバーライドの許可範囲 (外のモジュールからの継承・オーバーライド可能性) です。

関連: [public](#public), [private](#private), [internal](#internal), [fileprivate](#fileprivate)
参考: [The Swift Programming Language (Swift 3) # Access Control](https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/AccessControl.html#//apple_ref/doc/uid/TP40014097-CH41-ID3)

### operator
独自の演算子を定義します。
演算子として採用できる文字については規定があります。詳細は [iOS Developer Library の Language Reference > Lexical Structure > Operators](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/doc/uid/TP40014097-CH30-ID418) をご覧ください。
関連: [prefix](#prefix), [postfix](#postfix), [infix](#infix)

```swift
prefix operator ☁
prefix func ☁ (a: inout Int) -> Int {
    a *= a
    return a
}
postfix operator ***  // 複数文字列も可能
postfix func *** (a: inout Int) -> Int {
    a *= a
    return a
}
infix operator ☁
func ☁ (left: Int, right: Int) -> Int {
    return left + right
}

var hoge = 2
☁hoge    // => 4
hoge***  // => 16
1 ☁ 2    // => 3
```

###precedencegroup
左右に被演算子をとる演算子の優先度グループを定義します。
higherThan で、どのグループより優先度が高いか指定できます。lowerThan では、他のモジュールのどのグループより優先度が低いか指定できます。[associativity](#associativity) と [assignment](#assignment) も指定できます。

```swift:演算子を定義する構文
infix operator <#operator name#> : <#precedence group name#>
```

```swift:+++が先に評価される場合
precedencegroup GroupA {

    associativity: none
}
precedencegroup GroupB {
    
    higherThan: GroupA
    associativity: none
}

infix operator ***: GroupA
infix operator +++: GroupB

func *** (left: Int, right: Int) -> Int {
    return left * right
}
func +++ (left: Int, right: Int) -> Int {
    return left + right
}

1 +++ 1 *** 0  // => 0
```
関連: [operator](#operator), [associativity](#associativity), [assignment](#assignment)

### private
アクセス修飾子の一種です (クラス、変数、定数、メソッド、関数の公開範囲の指定)
最も制限の強いアクセス修飾子で、下記のように、定義されたスコープ内でのみアクセスできます。

```swift:privateのアクセス制限
class SampleClass {
    func otherScopefunc() {
        // ❗️error: use of unresolved identifier 'privateFunc'
        privateFunc()
    }
}

extension SampleClass {
    private func privateFunc() {}
    
    func sameScopefunc() {
        // OK
        privateFunc()
    }
}

let sample = SampleClass()
// ❗️error: use of unresolved identifier 'privateFunc'
sample.privateFunc()
```

関連: [public](#public), [internal](#internal)

### protocol
プロトコルを宣言します。

### public
アクセス修飾子の一種です (クラス、変数、定数、メソッド、関数の公開範囲の指定)
同じターゲット(モジュール)外からアクセス可能になります。主に、ライブラリなどで API として公開するものに対して指定します。
関連: [private](#private), [internal](#internal)

### static
static 変数や static メソッドを宣言します。
protocol での宣言時 (下記参照) は `class func` と `class var` も意味に含みます。

```swift
protocol SampleProtocol {
    static func staticFuncInProtocol()
    static var staticVarInProtocol: Int { get }
}

class Sample {
    // `static func staticFuncInProtocol()` can be implemented by `static func` or `class func`
    class func staticFuncInProtocol() {}
    // ditto
    class var staticVarInProtocol: Int { return 1 }
}
```

### struct
構造体を宣言します。

### subscript
クラスや構造体に [] を実装します。
Objective-C の場合については[クラスに [], {} を実装する](http://qiita.com/ezura/items/dd4ff9b0ae2a1afa3bb3)に書いてみました。

```swift:実装例
class SubscriptSample {
    var hoge: Any?
    subscript(index: Int) -> String {
        get {
            return "Int もらいました"
        }
        set {
            hoge = newValue
        }
    }
    
    subscript(index: String) -> String {
        get {
            return "String もらいました"
        }
        // setter なくても良いです
    }
    
    subscript(index: AnyObject?) -> String {
        return "何かもらいました"
    }
    
    subscript(x: Int, y: Int) -> String {
        return "\(x), \(y)"
    }

    subscript() -> String {
        return "nothing"
    }
}
```

```swift:使用例
let subscriptSample = SubscriptSample()
var optionalSample: Int? = 1;
subscriptSample[3]     // => "Int もらいました"
subscriptSample["a"]   // => "String もらいました"
subscriptSample[nil]   // => "何かもらいました"
subscriptSample[optionalSample]  // => "何かもらいました"
subscriptSample[1, 2]  // => "1, 2"
subscriptSample[]  // => "nothing"
```

### typealias
型の別名を宣言します。

```swift:使用例
typealias IntAlias = Int
typealias Point = (Int, Int)
```

参考: 
The Swift Programming Language (Language Reference -> Declaration -> Type Alias Declaration)
The Swift Programming Language (Language Reference -> Declaration -> Protocol Associated Type Declaration)

### associatedtype
associated type (付属型) の宣言をします。

```swift
protocol SampleProtocol {
    associatedtype AssociatedType      // 付属型を宣言します
    func sampleFunc(param :AssociatedType) -> AssociatedType
}

struct SampleStruct: SampleProtocol {
    func sampleFunc(param: Int) -> Int {  // 付属型が Int であると決定されます
        return param + param
    }
}
```

参考: 
The Swift Programming Language (Language Reference -> Declaration -> Type Alias Declaration)
The Swift Programming Language (Language Reference -> Declaration -> Protocol Associated Type Declaration)

### var
変数を宣言します。

## Keywords used in statements
### break
switch 文やループから抜けます。
[for](#for), [while](#while) の前にラベルをつけることで抜けるブロックを指定できます。
詳細: [document の Control Flow -> Labeled Statements] (https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/ControlFlow.html)

```swift
var i = 0
firstLoop: while true {
    print("first loop: \(i)")
    while true {
        i += 1
        print("second loop: \(i)")
        switch i {
        case 5:
            print("break firstLoop")
            break firstLoop
        default:
            break
        }
    }
}
print("finish: \(i)")
```

```実行結果
first  loop: 0
second loop: 1
second loop: 2
second loop: 3
second loop: 4
second loop: 5
break firstLoop
finish: 5
```

関連: [continue](#continue), [fallthrough](#fallthrough)

###case
列挙子リストの宣言、switch 文内で条件分岐、switch 文内以外で if, for との併用により、パターンマッチングができます。

```swift
let optionalSample: Int? = 1;
let optionalArraySample: [Int?] = [1, 2, nil, 3]

if case let x? = optionalSample {
    print("optionalSample:      \(x)")
}

for case let x? in optionalArraySample {
    print("optionalArraySample: \(x)")
}
```

```実行結果
optionalSample:      1
optionalArraySample: 1
optionalArraySample: 2
optionalArraySample: 3
```

参考: 
[Swift 2: Pattern Matching with “if case”](http://natashatherobot.com/swift-2-pattern-matching-with-if-case/),
[The Swift Programming Language (Patterns -> Optional Pattern)](https://developer.apple.com/library/mac/documentation/Swift/Conceptual/Swift_Programming_Language/Patterns.html)
関連: [enum](#enum)

###continue
次のループ処理へ移動します。
[break](#break) と同様にラベルをつけることで移動するループ処理を指定することができます。

```swift
var i = 0
firstLoop: while true {
    print("first  loop: \(i)")
    if i != 0 { break }
    while true {
        i += 1
        print("second loop: \(i)")
        switch i {
        case 5:
            print("continue firstLoop")
            continue firstLoop
        default:
            break
        }
    }
}
print("finish: \(i)")
```

```実行結果
first  loop: 0
second loop: 1
second loop: 2
second loop: 3
second loop: 4
second loop: 5
continue firstLoop
first  loop: 5
finish: 5
```

関連: [break](#break), [fallthrough](#fallthrough)

###default
switch 文内の条件分岐で、case に当てはまらなかった場合の処理の宣言をします。
関連: [switch](#switch), [case](#case)

###defer
スコープを抜ける際に実行する処理を記述します。

```swift
func deferSample() {
    defer {
        print("in defer")
    }
    print("end of scope")
}
deferSample()
```

```実行結果
end of scope
in defer
```

参考: 
[The Swift Programming Language (Statements -> Defer Statement)](https://developer.apple.com/library/mac/documentation/Swift/Conceptual/Swift_Programming_Language/Statements.html)
[The defer keyword in Swift 2: try/finally done right](https://www.hackingwithswift.com/new-syntax-swift-2-defer)

###do
スコープを作成します。
[catch](#catch)を繋げることで、スコープ内で発生した例外を[catch](#catch)文で処理することができます。
関連: [catch](#catch), [try](#try)

###else
条件分岐で使用します。
また、[guard](#guard)文では文法上必須となります。
関連: [if](#if), [guard](#guard)

###fallthrough
switch 文の中で、マッチした case 文の次の case 文または default 文内の処理を実行します。
(厳密には、`fallthrough` の所属している case ブロックの中から抜け、所属する case 文の次の case 文または default 文内の処理を実行します)

```swift:使用例
let a = 1
switch a {
case 1:
    print("1")
    fallthrough
case 2:
    print("2")
default:
    print("default")
}
```

```c:C言語の場合（上記と同等の処理）
switch (a) {
case 1:
    printf("1\n");
case 2:
    printf("2\n");
    break;
default:
    printf("default\n");
}
```

```実行結果
1
2
```

#### 補足
下記の補足です。
> 厳密には、`fallthrough` の所属している case ブロックの中から抜け、所属する case 文の次の case 文または default 文内の処理を実行します。

下記のように、`fallthrough` が呼ばれると、即座に case ブロックから抜けます。
そのため、その下の `print("1-2")` は実行されません。

```swift
switch 1 {
case 1:
    defer { print("defer") }  // ブロック(スコープ) から抜ける様子を観察
    print("1-1")
    if true {
        fallthrough
    }
    print("1-2")
case 2:
    print("2")
default:
    print("default")
}
```

```実行結果
1-1
defer
2
```

###for
繰り返し処理を記述できます。

```swift:for-in
for i in 1...10 {
    // 処理
}

for _ in 1...10 {
    // 処理
}
```

関連: [in](#in), [while](#while)

###guard
変数または定数が条件に一致するか評価し、一致していない場合、続く else のブロックが実行されます。
このブロックの中では必ず以下のいずれかを使用し、guard が記述されているスコープを抜けなくてはいけません。

* [return](#return)
* [break](#break)
* [continue](#continue)
* [throw](#throw)
* [fallthrough](#fallthrough)
* fatalError 等の `Never` 型を返す関数の呼び出し

```swift:
func guardSample1(value: Int?) -> String {
    guard let value = value, value > 10 else {
            // この中では必ずスコープを抜ける処理を書きます
            return "in else block"
    }
    // ここからは value がアンラップされ、また、10 より大きいことが保証されます
    return "\(value)"
}

guardSample1(nil)  // => in else block
guardSample1(10)   // => in else block
guardSample1(100)  // => 100
```

```swift
func guardSample2(a: String, b: Int?) -> String {
    // 複数の変数・定数の評価もできます
    guard let intValue = Int(a), let b = b else {
        return "in else block"
    }
    // ここからは b がアンラップされます
    return "\(intValue + b)"
}

guardSample2("a", b: 1)    // => in else block
guardSample2("1", b: 1)    // => 2
guardSample2("1", b: nil)  // => in else block
```

関連: [return](#return), [break](#break), [continue](#continue), [throw](#throw)

###if
続く条件を評価し、一致した(true)場合ブロック内を実行します。
unwrap する場合にも使用します。この構文を Optional binding と言います。詳細は[こちら ([Swift] Optional 型についてのまとめ Ver2)](http://qiita.com/cotrpepe/items/518c4476ca957a42f5f1) に解説されていて分かりやすかったです。

```swift
func ifLetSample(value: Int?) {
    if let a = value {
        type(of: value) // Optional<Int>.Type
        type(of: a)     // Int.Type
    }
}
```

関連: [else](#else), [guard](#guard)

###in
文脈によって下記のように意味が変わります。

* クロージャのボディの開始箇所を表します
* for ~ in の形で取り出す要素の配列を指定します

関連: [for](#for)

###repeat
C言語等の言語における

```c
do {...} while(...)
```

の `do` の役割です。
関連: [while](#while)

###return
返り値を指定します。
返り値は下記の 2 パターンです。

* 要素が一つの場合はその要素
* それ以外の場合は tuple

```swift
func sample() {
    return
}
var a = sample()　// -> ()
```

参考: [Remove @noreturn attribute and introduce an empty Never type](https://github.com/apple/swift-evolution/blob/master/proposals/0102-noreturn-bottom-type.md)

###switch
条件分岐を行います。

```swift
switch (1, "a") {
case (1, "b"):
    print("1, b")
case (1, _):
    print("1, _")  // ここがマッチします。 (_ はワイルドカード)
case (1, "a"):
    print("1, a")  // 上がマッチするので評価されません
}
```

関連: [case](#case)

###where
マッチングの条件を追加します。

###while
下記の2種類の繰り返し構文を記述できます。

```swift
while condition {
    statements
}
```

```swift
repeat {
    statements
} while condition
```

関連: [repeat](#repeat)

## Keywords used in expressions and types
### as
大きく分けて、2 種類の役割があります。
* キャスト

```swift
class A {}
let anyObj: AnyObject = A()
let a = anyObj as! A  // AnyObject から A にキャスト
```

* 型を明示すること

```swift
let v = 1 as Double
```

###Any
すべての型のインスタンス (関数型も含む) を表現します。

参考:
[Type Casting for Any and AnyObject](https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/TypeCasting.html#//apple_ref/doc/uid/TP40014097-CH22-ID342)
[Import Objective-C id as Swift Any type](https://github.com/apple/swift-evolution/blob/master/proposals/0116-id-as-any.md#import-objective-c-id-as-swift-any-type)

###catch
例外が投げられた際にブロック内が実行されます。

###false
真偽値リテラルの一種で、偽を表します。

###is
ある型またはあるプロトコルを実装した型として振る舞えるかどうかを検査します。

```swift
1 is Int             // -> true
(1, 1) is AnyObject  // -> false
(1, 1) is (Int, Int) // -> true

// プロトコルの検査
protocol SampleProtocol { }
class SampleClass: SampleProtocol { }

let sampleClassInstance = SampleClass()
sampleClassInstance is SampleClass      // true
sampleClassInstance is SampleProtocol   // true
```

###nil
nil リテラルを表します。

```swift
Optional.None == nil // -> true
```

###rethrows
引数にとったクロージャが投げた例外を呼び出し元に対して更に投げます。

```swift
func sample(callback: () throws -> Int) rethrows {
    try callback()
}
```


### super
親クラスを返します。

### self

* [インスタンスメソッド内などで単独で使用した場合、インスタンス自身を返します](#インスタンスメソッド内などで単独で使用した場合、インスタンス自身を返します)
* [expression (式) に対して呼び出した場合、式が評価された値が返ります](#expression (式) に対して呼び出した場合、式が評価された値が返ります  )
* [type (型) に対して呼び出した場合、自身の型が返ります](#type (型) に対して呼び出した場合、自身の型が返ります  )

#### インスタンスメソッド内などで単独で使用した場合、インスタンス自身を返します

```swift
class Sample {
    var a: Int?
    func sampleMethod() -> Sample {
        a = 1
        return self     // 自身 (playground 上では Sample と見えますが、プロパティ a が変更されているので上で作成したインスタンスだと確認できます)
    }
}
```

#### expression (式) に対して呼び出した場合、式がそのまま返ります  
` <#expression#>.self `

```(1 + 1).self``` の返り値は ```(1 + 1)``` という式と同等です。

```swift:式がそのまま返るとは
(1 + 1).self // (1 + 1)
```

```swift:余談
(1 + 1).self // 2 as Int ではない
// 証明
(1 + 1).self + 1.0 // OK
(1 + 1) + 1.0      // OK

let exp = 1 + 1    // 2 as Int
exp + 1.0          // Error (type mismatch)
```
 
#### type (型) に対して呼び出した場合、自身の型が返ります  
` <#type#>.self `

```swift
class Sample {
}
Sample.self    // -> Sample.Type    

Sample.self.init() // -> Sample のインスタンス (= Sample.self は自身の型を返しています)
```

参考: [The Swift Programming Language (Language Reference -> Expressions -> Postfix Self Expression)](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Expressions.html#//apple_ref/swift/grammar/postfix-self-expression)

###Self
自身の型を返します。

###throw
例外を投げます。

###throws
メソッド、関数の宣言部に書き、例外が投げられる可能性があることを示します。

###true
真偽値リテラルの一種で、真を表します。

###try
例外が投げられる可能性のある関数・メソッドを実行します。

##Keywords that begin with a number sign (#)

### \#available
OS 及びそのバージョンによる条件を表現します。

```swift
if #available(iOS 10.0, *) {
    print("iOS10 or later")
}
```

### \#colorLiteral
下記の構文で色を表現するリテラルを記述できます。

```
#colorLiteral­(­red­:­ <# expression #>­, ­green­:­ <# expression #>­,­ blue­:­ <# expression #>­,­ alpha­: <# expression #>­)­
```

型を明示しない場合は、AppKit モジュールをインポートした場合は NSColor 型、UIKit モジュールをインポートした場合は UIColor 型として解釈されます。

### \#column
\#column が評価された場所の列番号 (Int)

### \#if, \#else, \#elseif, \#endif
コンパイル時に指定のコードを含めるか否かを制御します。

```swift:条件例
#if <# Custom Flag に設定した名前 (設定せずにコンパイルすると無視される) #>
  print("DEBUG")
#endif

#if swift(>=3.0)
  print("Swift3.0")
#endif

#if arch(arm64)
  print("arm64")
#endif

#if os(OSX)
  print("OSX")
#endif
```

```swift:Swiftのバージョンを条件に制御する例
#if swift(>=3.0)
    print(">=Swift3.0")
#elseif swift(>=2.0)
    print(">=Swift2.0")
#else
    print("else")
#endif
```

参考: 
* [The Swift Programming Language (Swift 3) > Conditional Compilation Block](https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Statements.html#//apple_ref/swift/grammar/conditional-compilation-block)
* [CONDITIONAL COMPILATION](http://en.swifter.tips/condition-compile/)

### \#file
\#file が評価された場所のファイル名 (String)

### \#fileLiteral
下記の構文でファイルリテラルを記述できます。

```swift
#fileLiteral(resourceName: "<# ファイル名 #>")
```

型を明示しない場合は URL 型として解釈されます。（Foundation モジュールがインポートされている場合のみ）
また、ファイルが取得できなかった場合、実行時エラーとなります。

参考: 
* [Modernizing Playground Literals](https://github.com/apple/swift-evolution/blob/master/proposals/0039-playgroundliterals.md)
* [swift/test/Sema/object_literals_osx.swift](https://github.com/apple/swift/blob/master/test/Sema/object_literals_osx.swift#L19-L26)

### \#function
\#function が評価された場所の関数・メソッドの名前 (String) を表現します。

### \#imageLiteral
下記の構文で画像リソースを表現するリテラルを記述できます。

```swift
#imageLiteral(resourceName: "<# ファイル名 #>")
```

型を明示しない場合は、AppKit モジュールをインポートした場合は NSImage 型、UIKit モジュールをインポートした場合は UIImage 型として解釈されます。

### \#keypath
key や keypath (string literal) を生成します。

```swift
class Object: NSObject {
    let value = 1
    var matryoshka: Object?
}

#keyPath(Object.value)  // "value"
#keyPath(Object.matryoshka.value)  // "matryoshka.value"

let object = Object()
object.matryoshka = Object()

object.value(forKey: #keyPath(Object.value))  // 1
object.value(forKeyPath: #keyPath(Object.matryoshka.value))  // 1
```

関連:
* [\#keypath の proposal](https://github.com/apple/swift-evolution/blob/master/proposals/0062-objc-keypaths.md)
* [Swift3ではKVOにkeyPath()式を使っていくのが便利](http://qiita.com/yimajo/items/b752bc0ff21684c4c17a)

### \#line
\#line が評価された場所の行番号 (Int)

### \#selector
Selector を生成します。

Swift3 から、以前の機能に加え、Objective-C で記述された class のプロパティの getter, setter メソッドの Selector を `\#selector` を用いて生成できるようになりました。(以前は `\#selector` が対応していなかったため、文字列で指定していました)

```objc
@interface ViewController : UIViewController
@property(assign) int num;
@end
```

```swift
#selector(getter: ViewController.num)
#selector(setter: ViewController.num)
```

参考:
* [Using Swift with Cocoa and Objective-C (Swift 3) > Interacting with Objective-C APIs](https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithObjective-CAPIs.html#//apple_ref/doc/uid/TP40014216-CH4-ID59)
* [Hannibal #selector](https://www.bignerdranch.com/blog/hannibal-selector/)

### \#sourceLocation
\#line, #file の値を操作します。
(Swift2.2~ での #line の機能の一つが #sourceLocation に分離されました)

![Screen Shot 2016-10-15 at 20.54.58.png](https://qiita-image-store.s3.amazonaws.com/0/31285/40bf2e05-680a-59a3-42ca-910b04c846d3.png "Screen Shot 2016-10-15 at 20.54.58.png")
(注: 私の環境 [Xcode8.0] では #file が変化することを確認できませんでした)

参考:[The Swift Programming Language (Swift 3) > Line Control Statement](https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Statements.html#//apple_ref/swift/grammar/line-control-statement)

### \#dsohandle
\#line, \#filename, \#function と同様に、書かれている場所に関する情報を表すキーワードです。
自身が書かれているライブラリがロードされている場所のアドレスを表します。(アドレスなので、他のキーワードと違い、`UnsafePointer`型です)

> provides an UnsafePointer to the current dynamic shared object (.dylib or .so file)
> 引用: [Modernizing Swift's Debugging Identifiers](https://github.com/apple/swift-evolution/blob/master/proposals/0028-modernizing-debug-identifiers.md)

## 特定の文脈でのみ予約語として使用
### assignment
左右に値を取る演算子を宣言した際に、Optional Chaining 評価の一連の流れで演算するかを指定します。
true を指定すると、Optional Chaining 評価の一環として演算を行おうとします。false は既定の動作で、Optional Chaining の評価が終わってから、その評価結果と演算します。

```swift:オプショナルチェイニングでの畳み込み
precedencegroup OperationFoldedIntoOptionalChaining {
    assignment: true
}

precedencegroup OperationOutsideOfOptionalChaining {
    assignment: false
}

infix operator ~~ : OperationFoldedIntoOptionalChaining
infix operator ~^ : OperationOutsideOfOptionalChaining

func ~~ (left: Int, right: Int) -> Int {
    print("~~")
    return left + right
}

func ~^ (left: Int?, right: Int) -> Int {
    print("~^")
    return left?.advanced(by: right) ?? -1
}

let values = nil as [Int]?

values?.count ~~ 5  // => nil
values?.count ~^ 5  // => -1

/*
    ~~ 演算は、
        最初に `values` の nil 判定、nil でなければ `.count ~~ 5` を評価
        values.map { $0.count ~~ 5 } と同等。この例では `~~` 演算は実行されない。

    ~^ 演算は、最初に `values?.count` を評価、続いて `その結果 ~^ 5` を評価
        普通に `(values?.count) ~^ 5` としたのと同等。演算子の既定の動作。
*/
```

関連: [infix](#infix), [operator](#operator), [precedencegroup](#precedencegroup)

### associativity
左右に値を取る優先度グループを宣言した際に、結合方向を指定します。
指定できる値は下記の 3 種類です。

* [left](#left)  
* [right](#right)
* [none](#none): 結合方向を指定しないため、同じグループの演算子同士を並べて使用することができなくなります。

```swift:優先度グループを定義する構文
precedencegroup <#precedence group name#> {
    higherThan: <#lower group name#>
    associativity: <#left | right | none#>
}
```

```swift:同優先度、結合方向　none
precedencegroup MyAddition {
    associativity: none
}

infix operator +++ : MyAddition
infix operator --- : MyAddition

func +++ (left: Int, right: Int) -> Int {
    return left + right
}

func --- (left: Int, right: Int) -> Int {
    return left - right
}

1 +++ 1 --- 1
/*
 error: adjacent operators are in non-associative precedence group 'MyAddition'
 1 +++ 1 --- 1
   ^     ~~~
 */
```

関連: [left](#left), [right](#right), [none](#none), [operator](#operator), [precedencegroup](#precedencegroup)

###convenience
[init](#init) の前に記述することで、convenience initializer を宣言します。
関連: [init](#init)

###dynamic
Objective-C のランタイムを使用して値にアクセスします。

```swift:構文例
dynamic <#var | let #> <# name #>
```

###didSet
Stored プロパティまたは変数の値が変更された際の処理を宣言します。

###final
継承、オーバーライドを不可にします。

###get
文脈によって意味が異なります。

#### computed property 内: プロパティにアクセスした際の処理

```swift
class A {
    var value: Int {
        get { return 1 }
    }
}
```

#### protocol 内で宣言した場合: 値が取得可能であることの宣言

```swift
protocol Sample {
    var value: Int { get }
}

class A: Sample {
    let value = 1
}

class B: Sample {
    var value: Int { return 1 }
}
```

###infix
左右に被演算子をとる演算子の処理を定義します。

```swift
infix operator ☁
func ☁ (left: Int, right: Int) -> Int {
    return left + right
}

1 ☁ 2    // => 3
```

関連: [operator](#operator)

###indirect
列挙体を列挙子の中で再帰的に使えるようになります。
詳細:
indirect を指定すると付加情報を間接指定するようになります。
間接指定しない場合、付加情報のメモリサイズが確定できないため、その列挙体のために確保するメモリサイズも決まりません。
間接指定する場合、付加情報の場所(アドレス)を保持することになるので列挙体のサイズが確定できるようになります。

```swift
indirect enum SampleEnum {
    case Num(Int)
    case IndirectNum(SampleEnum)
}

SampleEnum.IndirectNum(SampleEnum.IndirectNum(SampleEnum.IndirectNum(SampleEnum.Num(1))))
```

[indirect](#indirect) は列挙子の前に書くことも可能です。

```swift
enum SampleEnum {
    case Num(Int)
    indirect case IndirectNum(SampleEnum)
}
```

詳細: [Swift Programming Language (Enumerations -> Recursive Enumerations)](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Enumerations.html#//apple_ref/doc/uid/TP40014097-CH12-ID536)

###lazy
遅延評価します。

###left
演算子を定義した際に、左結合を指定します。
詳細: [このページの associativity 項](#associativity)
関連: [associativity](#associativity), [operator](#operator), [right](#right), [none](#none)

###mutating
値型のオブジェクトにおいて、自身または自身のプロパティを書き換えるインスタンスメソッドに対して宣言する。

```swift:列挙体の場合
enum SampleEnum {
    case A, B, C
    case a, b, c
    mutating func upperCase() {
        switch self {
        case .a: self = .A
        case .b: self = .B
        case .c: self = .C
        default: break
        }
    }
}
```

```swift:構造体の場合
struct SampleStruct {
    var x = 0
    mutating func modifyX(x: Int) {
        self.x = x
    }
    mutating func reset() {
        self = SampleStruct()
    }
}
```

###none
演算子を定義した際に、結合方向を指定しません。
詳細: [このページの associativity 項](#associativity)
関連: [associativity](#associativity), [operator](#operator), [right](#right), [left](#left)

###nonmutating
値型のインスタンスメソッドが自身に変更を加えないことを宣言します。

使い所:
computed property 内で定義する set はデフォルトで [mutating](#mutating) になります。iOS の API 内では下記のように setter の mutaing を無効にするために使用しています。

```swift
var value: Value { get nonmutating set }
```

###optional
プロトコルで指定されたメソッドやプロパティの実装を任意とします。

###override
親クラスのメソッドやプロパティをオーバーライドする際に宣言します。

###postfix
独自の後置演算子を定義します。

```swift
postfix operator ***
postfix func *** (a: inout Int) -> Int {
    a *= a
    return a
}
var hoge = 4
hoge***  // => 16
```

関連: [prefix](#prefix), [infix](#infix), [operator](#operator)

###prefix
独自の前置演算子を定義します。

```swift
prefix operator ***
prefix func *** (a: inout Int) -> Int {
    a *= a
    return a
}
var hoge = 4
***hoge  // => 16
```

関連: [postfix](#postfix), [infix](#infix), [operator](#operator)

###Protocol
Protocol のメタタイプを取得します。

```swift
let protocolMetatype: SampleProtocol.Protocol = SampleProtocol.self
```

関連: [Type](#Type)

###required
サブクラスにイニシャライザのオーバーライドを強制します。
また、サブクラスでそのイニシャライザをオーバーライドする際には [override](#override) ではなく、required を指定します。

###right
演算子を定義した際に、右結合を指定します。
詳細: [このページの associativity 項](#associativity)
関連: [associativity](#associativity), [operator](#operator), [left](#left), [none](#none)


###set
文脈によって意味が異なります。

#### computed property 内: プロパティにアクセスした際の処理

```swift
class A {
    var value: Int {
        get { return 1 }
        set {}
    }
}
```

#### protocol 内で宣言した場合: 値を受け渡し可能であることを宣言

```swift
protocol Sample {
    var value: Int { get set }
}

class A: Sample {
    var value = 1
}

class B: Sample {
    var value: Int {
        get { return 1 }
        set {}
    }
}
```

###Type
クラス、構造体、列挙体のメタタイプを取得します。

```swift
class Sample {
    required init() {}
}

let metatype: Sample.Type = Sample.self
let instance = metatype.init()
```

関連: [Protocol](#Protocol)

###unowned
弱参照の変数を宣言します。
[weak](#weak) と違い、参照している値よりも生存期間が短い、つまり、アクセスした際に参照先が解放されていない (nil となっていない) ことを前提とします。値が破棄されているとランタイムエラーになります。

```swift
// unowned = unowned(safe)
unowned var safe: AnyObject

// capture list 内で指定することが多いです
{ [unowned a] in /* ... */ }
```

関連: [weak](#weak), [unowned(safe)](#unowned(safe)), [unowned(unsafe)](#unowned(unsafe))

###unowned(safe)
`unowned` へ修飾することで参照の動作を指定できます。
`unowned`(何も指定しなかった場合)は `unowned(safe)` 扱いとなります。対となる指定に [`unowned(unsafe)`](#unowned(unsafe)) があります。

```swift
// unowned = unowned(safe)
unowned(safe) var safe: AnyObject

// capture list 内で指定することが多いです
{ [unowned(safe) a] in /* ... */ }
```

関連: [unowned(unsafe)](#unowned(unsafe)), [unowned](#unowned)

###unowned(unsafe)
`unowned` へ修飾することで参照の動作を指定できます。
`unowned` または `unowned(safe)` と違い、参照先が解放された際にアクセスしても `nil` になりません。つまり、解放されている場所を指し続けているためメモリに対して安全なアクセスをしません。
Objective-C の `__unsafe_unretained` と同様の動作です。

```swift
// like `__unsafe_unretained`
unowned(unsafe) var unsafe: AnyObject
{ [unowned(unsafe) a] in /* ... */ }
```

関連: [unowned(safe)](#unowned(safe)), [unowned](#unowned)

###weak
弱参照の変数を宣言します。
[unowned](#unowned) と違い、参照している値が nil になることを許容します。

###willSet
stored property または変数への代入が実行される前の処理を記述します。
関連: [didSet](#didSet)

## その他
### _
#### ワイルドカード

```swift
switch (1, "a") {
case (1, "b"):
    print("1, b")
case (1, _):
    print("1, _")  // ここがマッチします。 (_ はワイルドカード)
}
```

関連: [case](#case)

#### 引数名の省略

```swift:引数が必要なinit
class Sample {
    var a: Int
    init(param: Int) {
        a = param
    }
}
let sample = Sample(param: 1)
```

```swift:引数が不要なinit
class Sample {
    var a: Int
    init(_ param: Int) {
        a = param
    }
}
let sample = Sample(1)
```

#### 値を捨てる
```swift
let a: Int
(a, _) = (0, 1)
a // -> 0
```