post Image
Swift4 全予約語 (98語) の解説

Outline

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

ドキュメントから漏れている予約語もあるため、下記情報を統合してカウントしています。
* The Swift Programming Language (Swift 4) Lexical Structure
* The Swift Programming Language (Swift 4) Summary of the Grammar
* https://github.com/apple/swift/include/swift/Syntax/SyntaxKinds.def

宣言 (declarations)

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

class  

場所によって意味が異なります。

  • クラスの宣言や、メソッドやプロパティの前に指定することでクラスメソッド、クラスプロパティの宣言をします。
class Sample {
    var member = 1
}

let a = Sample()
let b = a
a === b       // -> true (指すものは同じ)
a.member = 2
b.member      // -> 2
  • プロトコルで、適用先をクラスだけに制限したいときにも使います。
protocol SampleProtocol : class {

}

class Sample : SampleProtocol {

}

deinit

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

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
出力
Sub Class's deinit is called
Super Class's deinit is called

enum

列挙型の宣言をします。

extension

定義済みのクラス、構造体、プロトコル、列挙型に対して function または computed property を追加します。
where で適応する条件を指定できます。

fileprivate

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

関連: public, private, internal, open
参考: The Swift Programming Language # Access Control

func  

function の宣言をします。

import

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

init

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

inout

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

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

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

internal

アクセス修飾子の一種です。
同じモジュール内からアクセスできます。
アクセス修飾子をつけなかった場合、デフォルトで internal となります。
関連: public, private, open, fileprivate
参考: The Swift Programming Language (Swift 3) # Access Control

let

定数を宣言します。
関連: var

open

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

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

関連: public, private, internal, fileprivate
参考: The Swift Programming Language # Access Control

operator

独自の演算子を定義します。
演算子として採用できる文字については規定があります。詳細は iOS Developer Library の Language Reference > Lexical Structure > Operators をご覧ください。
関連: prefix, postfix, infix

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 では、他のモジュールのどのグループより優先度が低いか指定できます。associativityassignment も指定できます。

演算子を定義する構文
infix operator <#operator name#> : <#precedence group name#>
+++が先に評価される場合
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, associativity, assignment

private

アクセス修飾子の一種です (型、変数、定数、function の公開範囲の指定)
最も制限の強いアクセス修飾子で、下記の条件を満たす場合のみにアクセスできます。

  • 同じファイル内
  • 同じ型
class A {
    private var privateVar = ""
}

extension A {
    func f() {
        // ✅OK
        print(privateVar)
    }
}

class B {
    let a = A()
    func f() {
        // ❗️error: 'privateVar' is inaccessible due to 'private' protection level
        a.privateVar
    }
}

関連: public, internal, open

protocol

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

public

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

static

static 変数や static function を宣言します。
protocol での宣言時 (下記参照) は class funcclass var も意味に含みます。

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 の場合についてはクラスに [], {} を実装するに書いてみました。

実装例
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"
    }
}
使用例
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

型の別名を宣言(1)、または、associated type に対して型を指定(2)します。

型の別名を宣言(*1)
typealias IntAlias = Int
typealias Point = (Int, Int)
付属型に対して型を指定(*2)
protocol P {
    associatedtype T
}

struct S: P {
    typealias T = Any
}

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

associatedtype

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

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, while の前にラベルをつけることで抜けるブロックを指定できます。
詳細: document の Control Flow -> Labeled Statements

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, fallthrough

case

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

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”,
The Swift Programming Language (Patterns -> Optional Pattern)
関連: enum

continue

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

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, fallthrough

default

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

defer

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

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

参考:
The Swift Programming Language (Statements -> Defer Statement)
The defer keyword in Swift 2: try/finally done right

do

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

else

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

fallthrough

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

使用例
let a = 1
switch a {
case 1:
    print("1")
    fallthrough
case 2:
    print("2")
default:
    print("default")
}
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") は実行されません。

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

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

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

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

関連: in, while

guard

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

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
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, break, continue, throw

if

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

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

関連: else, guard

in

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

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

関連: for

repeat

C言語等の言語における

do {...} while(...)

do の役割です。
関連: while

return

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

  • 要素が一つの場合はその要素
  • それ以外の場合は tuple
func sample() {
    return
}
var a = sample() // -> ()

参考: Remove @noreturn attribute and introduce an empty Never type

switch

条件分岐を行います。

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

関連: case

where

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

while

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

while condition {
    statements
}
repeat {
    statements
} while condition

関連: repeat

Keywords used in expressions and types

as

大きく分けて、2 種類の役割があります。
* キャスト

class A {}
let anyObj: AnyObject = A()
let a = anyObj as! A  // AnyObject から A にキャスト
  • 型を明示すること
let v = 1 as Double

Any

すべての型のインスタンス (関数型も含む) を表現します。
実態は空の protocol です。

参考:
Type Casting for Any and AnyObject
Import Objective-C id as Swift Any type

catch

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

false

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

is

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

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 リテラルを表します。

Optional.None == nil // -> true

rethrows

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

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

super

親クラスを表します。

self

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

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

expression (式) に対して呼び出した場合、式がそのまま返ります

<#expression#>.self

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

式がそのまま返るとは
(1 + 1).self // (1 + 1)
余談
(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

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

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

参考: The Swift Programming Language (Language Reference -> Expressions -> Postfix Self Expression)

Self

自身の型を返します。

throw

例外を投げます。

throws

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

true

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

try

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

Keywords that begin with a number sign (#)

#available

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

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

コンパイル時に指定のコードを含めるか否かを制御します。

条件例
#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のバージョンを条件に制御する例
#if swift(>=3.0)
    print(">=Swift3.0")
#elseif swift(>=2.0)
    print(">=Swift2.0")
#else
    print("else")
#endif

参考:
* The Swift Programming Language > Conditional Compilation Block
* CONDITIONAL COMPILATION

#file

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

#fileLiteral

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

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

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

参考:
* Modernizing Playground Literals
* swift/test/Sema/object_literals_osx.swift

#function

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

#imageLiteral

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

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

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

#keypath

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

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
* Swift3ではKVOにkeyPath()式を使っていくのが便利

#line

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

#selector

Selector を生成します。

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

@interface ViewController : UIViewController
@property(assign) int num;
@end
#selector(getter: ViewController.num)
#selector(setter: ViewController.num)

参考:
* Using Swift with Cocoa and Objective-C (Swift 3) > Interacting with Objective-C APIs
* Hannibal #selector

#sourceLocation

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

Screen Shot 2016-10-15 at 20.54.58.png
(注: 私の環境 [Xcode8.0] では #file が変化することを確認できませんでした)

参考:The Swift Programming Language (Swift 3) > 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

特定の文脈でのみ予約語として使用

assignment

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

オプショナルチェイニングでの畳み込み
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, operator, precedencegroup

associativity

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

  • left
  • right
  • none: 結合方向を指定しないため、同じグループの演算子同士を並べて使用することができなくなります。
優先度グループを定義する構文
precedencegroup <#precedence group name#> {
    higherThan: <#lower group name#>
    associativity: <#left | right | none#>
}
同優先度、結合方向 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, right, none, operator, precedencegroup

convenience

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

dynamic

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

構文例
dynamic <#var | let #> <# name #>

詳細

Objective-C runtime と pure Swift では、呼び出す処理を決定する方法 (method dispatch) が異なります。
Objective-C runtime の場合、実行時に Class に対して問い合わせて実行すべき処理を探していきます (message passing 方式)。
例えば、instance.methodA() を実行するとき、instance の持つ Class の情報に対して、”methodA” (呼び出したい function 名) があるか検索します。無かったらその Class の親 Class に対して問い合わせる、なかったら更にその親 Class に、といった処理を実行時に行います。
一方、Swift ではコンパイル時に「型に対してどんな method があるか」という情報を持つ table を作ります。直接呼び出す場合もありますが、継承関係がある場合など、実行時にしか呼び出す処理が決まらない場合はこの table を参照して処理を決定します。重要なのは、この table はコンパイル時に作られてから後で変更できないということです。
Objective-C の場合、Class の情報を書き換えることができます。つまり、実行時に method を増やしたり、method 名を変えたり、処理を入れ替えたりできます。
このような Objective-C の機能を使いたい場合、dynamic を指定することで、Swift の method table 上には載らず、Objective-C の機構を使って処理するようになります。

didSet

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

final

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

get

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

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

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

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

protocol Sample {
    var value: Int { get }
}

class A: Sample {
    let value = 1
}

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

infix

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

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

1  2    // => 3

関連: operator

indirect

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

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

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

indirect は列挙子の前に書くことも可能です。

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

詳細: Swift Programming Language (Enumerations -> Recursive Enumerations)

lazy

遅延評価します。

left

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

mutating

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

列挙体の場合
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
        }
    }
}
構造体の場合
struct SampleStruct {
    var x = 0
    mutating func modifyX(x: Int) {
        self.x = x
    }
    mutating func reset() {
        self = SampleStruct()
    }
}

none

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

nonmutating

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

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

var value: Value { get nonmutating set }

optional

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

override

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

postfix

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

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

関連: prefix, infix, operator

prefix

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

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

関連: postfix, infix, operator

Protocol

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

let protocolMetatype: SampleProtocol.Protocol = SampleProtocol.self

関連: Type

required

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

right

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

set

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

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

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

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

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

class A: Sample {
    var value = 1
}

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

Type

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

class Sample {
    required init() {}
}

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

関連: Protocol

unowned

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

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

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

関連: weak, unowned(safe), unowned(unsafe)

unowned(safe)

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

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

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

関連: unowned(unsafe), unowned

unowned(unsafe)

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

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

関連: unowned(safe), unowned

weak

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

willSet

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

その他

_

ワイルドカード

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

関連: case

引数名の省略

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

値を捨てる

let a: Int
(a, _) = (0, 1)
a // -> 0

『 Swift 』Article List