僕がSwiftで使ってる構文のメモ

## はじめに
この文献はSwiftの基本構文の説明ではなく、僕が使っている構文で便利なものをまとめたものです。
なので、基本的構文の一部は割愛されてます。
※便利な構文を随時追加していきます。

これ以外にも他にも便利な構文があればコメントで教えていただけると僕が喜びます。

## 改定履歴
* 2015/7/16
enum追記、Array,Dictionaryの初期化を追記。
for文でeach_with_index的なものの追記。
Enumでコンパイルエラーが発生するケースを追記。

* 2015/7/19
Arrayの存在確認を追加

* メモ
setメソッドのハック、Lazy、filterなどもいずれ書く。

## OptionalValue
Swiftと言えば`OptionalValue`と言うほど便利な構文です。
あまりに基本的な構文なので構文の説明は割愛して、僕が使う局面について説明します。

### 非Optional 型

```swift
var str = "初期化コード"
```

nilが入ることが絶対なく、nilを考慮するプログラムを書くことが面倒な場合に使用します。
この構文は必ず初期化をしなければならない。

OptionalValueは便利だが、僕は極力nilが入らないコードを作るようにプログラムを心がけているので非Optionalの方が使用頻度が高いです。


### Optional 型

```swift
var str:String?
var human:Human?
```

使用方法

```swift
str = "Optionalデータ"
if let s = str {
    print("\(s)")
}

human = Human()
human?.run()
human!.run()	// 値が入っていることがわかっている場合は`!`で呼び出すこともある。
human?.foot?.kick()	// チェーンしても問題ない。途中でnilがある場合はそれ以降の行われずnilと評価される。
```

Optinal型はアンラップしないと実際の定義値が使えないため、簡単なことをする場合でも手間がかかるときがある。
しかし、強固なアプリを作る上では絶対不可欠なのでSwiftを行う上では覚えておく必要がある。
かなり奥が深い構文なので、深く知りたい方はkoherさんの[SwiftのOptional型を極める](http://qiita.com/koher/items/c6f446bad54442a28bf4)を見ると勉強になる。

また、Swift1.2から複数のOptional型を同時にアンラップできるようになった。

````swift
if let s = str, let h = human {
    print("\(s)")
}
````

僕は極力nilを含めないようなプログラムを心がけているため、主に以下のケースで使用する。

* 他のクラスが強参照しているオブジェクトを一時的に借りる場合。（主にweakと合わせて使う。）
* コールバック系の処理など、格納されるかどうかわからない処理を扱う場合。
* cocoaなどのフレームワークからの戻り値がOptional型の場合。

ちなみに関数をOptionalで扱う場合は以下のような構文になる。

```swift
var callback:(()->())?
```

外側のカッコが重要。
`()->()`で関数の型を定義していて、その関数をくくるために外側のカッコをつけている。

使用方法

```swift
callback = { () in
...
// コールバックの処理
}

// 呼び出し処理
callback?()
```

などになる。
関数の書き方はいろいろあるので、慣れてきたら略式で書くと工数が削減できる。（後述）

※weakについては僕の記事の[weak（弱参照)の使うタイミング(特にクロージャの中)について説明してみる](http://qiita.com/syou007/items/51f2342850e408739cc9)などを見てもらえると嬉しい。

### Implicitly unwrapped optional 型

````swift
var str:String!
````

`非Optional型`と同じように使えるが、nilをチェックしない`Optional型`です。
絶対に値は入っているが、初期化時には値が入れない場合に使用する。

主に使用するのはxibやstoryboardなどによってオブジェクトが挿入される時だろう。

例

```swift
@IBOutlet weak var text:UITextField!
```

使用方法は`非Optional型`と同じように扱ってほとんど問題がない。
nilが挿入される可能性が少しでもあるなら`Optional型`を使うべきだろう。

## private / final
説明は不要だと思うが、オブジェクト指向のカプセル化で使用する。
動的ディスパッチを減らす意味でも積極的につけていくとパフォーマンスが向上する。
・・・とは言っても、劇的な効果があるわけではないので気づいたらfinalをつけていこうって感じ。

## 同期処理
gfxさん[Swiftでマルチスレッド時の同期処理はどうやるのか](http://qiita.com/gfx/items/532f9f975de5a965c58a)がとても便利。
記事の内容の転記だが、以下のコードを使うことで同期処理が簡単にできる。（使い方はgfxさんの記事をみてください。）

```swift
class AutoSync {
    let object : AnyObject

    init(_ obj : AnyObject) {
        object = obj
        objc_sync_enter(object)
    }

    deinit {
        objc_sync_exit(object)
    }
}
```

このコードのポイントはblock構文を使わないため、インテントが深くならずに書きやすいところだ。

## 関数の書き方色々
僕はものぐさなので、できるだけ簡単に関数を書きたい。
その例をいくつか書いてみる。

### 通常関数引数の呼び出し方
関数を引数にする場合は基本的に最後に記載すること。
Swiftでは最後に関数がある場合に、スマートに呼び出すことができる。

````swift
func function(str:String, callback:()->()) {
// なんらかの処理
callback()
}
````

普通に呼び出すと以下のようになる。

````swift
function("引数", { () in
	// コールバックとしての処理
})
````

省略して呼び出すと以下のようになる。

````swift
function("引数", {
	// コールバックとしての処理
})
````

スマートに呼び出すと以下のようになる。

````swift
function("引数") {
	// コールバックとしての処理
}
````

どれも同じ挙動をするが、一番最後の呼び出し方法がSwift的に綺麗な記述方法だろう。
※カッコを閉じる位置に注目してください。

#### 引数がある場合
引数がある場合でも省略して書ける。

````swift
func function(str:String, callback:(human:Human)->()) {
// なんらかの処理
callback(Human())
}
````

普通に呼び出すと以下のようになる。

````swift
function("引数", { (human) in
	// コールバックとしての処理
	human.run()
})
````

スマートに呼び出すと以下のようになる。

````swift
function("引数") { (human:Human) in
	// コールバックとしての処理
	human.run()
}
````

変数の型を省略して書くと以下のようになる。

````swift
function("引数") { (human) in
	// コールバックとしての処理
	human.run()
}
````

変数の定義すら省略すると以下のようになる。

````swift
function("引数") {
	// コールバックとしての処理
	$0.run()
}
````

変数を省略する場合は、`$0,$1,$2...`の順番に引数が設定される。
引数が渡ってきているのに、`$0`などを記載しないとコンパイルエラーになる。

以下のコードは`$0`を使っていないのでコンパイルエラー。

````swift
function("引数") {
	// コールバックとしての処理
	print("コンパイルエラー")
}
````

### 変数として定義している関数の設定の仕方
funcを使わずに、関数を変数として定義した場合に設定すると以下のようになる。

````swif
// 定義
var function:()->()

// 処理の設定
function = { () in
	// 呼び出したい処理
}

function()
````

上記同様で以下のようなことも可能

````swif
// 定義
var function:(human:Human)->()

// 処理の設定
function = {
	// 呼び出したい処理
	$0.run
}

function(Human())
````

## キャプチャーリスト
objective-cやswiftにはガベージコレクション(GC)がないので、変数の管理は自分で行う必要がある。
例えば、ある画面でボタンを押したらWebサービスからデータを取得するような処理を書くと以下のようになる。

````swift
@IBAction func onClick(sender:AnyObject) {
	// APIを呼び出す処理
	API.call() {
		// APIの結果を画面に描画する。
		self.write($0)
	}
}
````

この処理は画面が切り替わる前にAPIの結果が返って来れば問題ないが、APIの結果が返ってくる前に画面遷移等をして画面が無くなってしまうと予期せぬ挙動が発生する。
その理由は`self.write($0)`の部分のselfのオブジェクトが`API.call()`によってキャプチャー（強参照）されてしまっているからである。

詳細は割愛するが、self（UIViewController）のオブジェクトが壊れている状態に対して`write()`などの関数を呼び出してしまっているため予期しない挙動が発生する。
この手のエラーは見つけるのが困難なので、非同期処理をする場合は極力このようなコードは書かないようにすべきである。

で、どうするかというとキャプチャーリストとしてweak（弱参照）を定義しておくのだ。

````swift
@IBAction func onClick(sender:AnyObject) {
	// APIを呼び出す処理
	API.call() { [weak self] in
		// APIの結果を画面に描画する。
		self?.write($0)
	}
}
````

構文としてのポイントは`[weak self] in`この部分だ。
この構文によって、selfは使いたいけど変数が解放されていたら無視したいということができる。
これによって、ブロック構文内では`self`がOptional型に変わり、`self?`でアクセスできるようになる。
※キャプチャーリストを使う場合は最後にある`in`を省略できないので注意。

self?は弱参照なので、画面遷移などが発生した場合はnilになっている。
また、コールバック後に長い処理を行うと処理の途中で`self?`がnilになる場合が発生してしまう。
その場合は以下のような構文で対応するとよい。

````swift
@IBAction func onClick(sender:AnyObject) {
	// APIを呼び出す処理
	API.call() { [weak self] in
		// APIの結果を画面に描画する。
		if let _self = self {
			_self.write($0)
			// 長い処理・・・
		}
	}
}
````

`if let _self = self`によって`self?`を`_self`で強参照しているためif文の中で`self?`が解放されることがなくなる。

また、キャプチャーリストは以下のように複数定義することもできる。

````swift
@IBAction func onClick(sender:AnyObject) {
	// APIを呼び出す処理
	API.call() { [weak self, myButton, myObjyect] in
		// APIの結果を画面に描画する。
		self?.write($0)
	}
}
````

## 変数が空だったら初期化する
Rubyの場合は以下のような構文によって、@objectが空だったら初期化するというコードが使える。

````ruby
@object ||= Object.new
````

これは部分的にキャッシュしたりするときにとても有効なのだが、残念ながらswiftにはない。
しかし、工夫をすると同じようなことができる。

````swift
self.object = self.object ?? Object()
````

`??`の構文は左の値がnilの場合は右の値を使用するという構文。
以下と等価です。

````swift
self.object = self.object != nil ? self.object : Object()
````

## キャスト
Swiftでキャストする場合は二種類の方法があります。
プリミティブ型っぽいもの（Integer,Int32、Int64,Flort,etc...）の場合は以下のように行います。

````swift
let floatObj = 0.5
let intObj = Int32(floatObj)
````
これは厳密にはキャストではなく型を変えてます。
なので、`floatObj`と`intObj`は別物です。

他のオブジェクト型の場合

````swift
class ObjectParent {}
class objectChild : ObjectParent {}

let objectParent = ObjectParent()
let objectChild = objectChild as? ObjectChild
````
この結果は`objectChild`に`nil`が入ります。
`objectChild`はOptinal型です。
`as?`はダウンキャストができるかをチェックしてできない場合にnilを返します。

````swift
let objectParent = ObjectParent()
let objectChild = objectChild as! ObjectChild    // 実行時エラー！
````
`ObjectParent`は`ObjectChild`ではないので、`as!`は強制的にダウンキャストを行うので上記の場合は実行時エラーが発生します。

````swift
let objectParent = ObjectChild()
let objectChild = objectChild as! ObjectChild
````
この場合はダウンキャストが成功します。
また、`objectParent`と`objectChild`は同一オブジェクトになります。

````swift
let objectParent = ObjectChild()
let objectChild = objectChild as? ObjectChild
````
この場合もダウンキャストは成功しますが`objectChild`はOptional型なので`objectParent`と`objectChild!`が同じオブジェクトになります。

主な使用例は以下のようになります。

````swift
let objectParent = ObjectChild()
if let objectChild = objectChild as? ObjectChild {
	// objectChildの場合の処理を記載
} else {
	// objectParentの場合の処理を記載
}
````

as?は非常に便利な構文です。
覚えておいて損はないでしょう。
また、OptionalValueの`?`や`!`とは別物なので注意してください。

## enum
enumはかなり便利です。

````swift
enum Type {
	case A
	case B
}
````

このように普通に使えますし、関数を使って拡張もできます。
しかし、僕が一番便利だと思っているのは

````swift
enum TypeString:String {
    case A = "a"
    case B = "b"
}

// 文字列からEnumを生成。Optional型。
let typeString = TypeString(rawValue: "a")
print("type = |(typeString!.rawValue())"
````

この構文です。
enumに型をつけれるようになったので、型からenumが生成できるようになります。
どこで役に立つかというと、メタプロで外部からの情報を元にプログラムを動かす時にenumに定義していない値が送られてきたらエラーを発生させれるところです。
他にも、最終的には文字列として処理をしたいけどリテラルな値を持ち回りたくない（コンパイルエラーが出ないから）という時などにとても便利です。（もちろんString以外でも同様のことができます。NSUserDefaultsとも相性が良いです。）

ちなみに上記の構文では`typeString`はOptional型になります。
定義されていない文字を渡すとnilが返却されます。

### 略式
enumは略して書くこともできる。
例えば以下のようなenumとfuntionがあったとする。

```swift
enum TestEnum {
    case TestA
    case TestB
}

func test(testEnum:TestEnum) {}
```

この関数を呼び出す場合は普通は以下のように記載します。

```swift
test(TestEnum.TestA)
```

しかし、swiftでは型がわかっている場合はオブジェクトを省略できます。

```swift
test(.TestA)
```

という記述が可能になります。
この省略記号はとても便利なのですが、XCode6.4現在ではコード補完がほとんど働きません。
Swich構文以外は働かないんじゃないかな・・・？
というくらい補完が出てきませんので、使うときには頑張ってタイピングしてください。

## クラスの中身を書き換える。
Objective-cにあったカテゴリーという機能はSwiftではありません。
代わりに`extension`という構文でクラスの中身を変えることができます。
<del>Objective-cではファイル単位でカテゴリーを適用させることができましたが、Swiftでは一括適用をするしかありません。</del>
（コメントにて指摘され、修正。）

````swift
extension String {
	func text() -> String {
		retrun "test"
	}
}
````

書いておきながら、僕はあまり`extension`を使いません。
`extension`はいざという時に使うものであって、乱用すべきではないと思います。

しかし、設計上巨大なクラスになることが分かっているクラスを分割するなどの場合には結構有効だったりします。
また、`NSArray`にはあるけど`Array`にはない関数を追加する場合に使えます。

2015/07/16 追記
* * *

## Arrayの初期化
Arrayの初期化は以下の構文で行えます。
どれも結果は同じになります。

```swift
// 空で初期化
let array:[String] = []
let array:[String] = Array()
let array:[String] = [String]()
let array = [String]()

// データを入れて初期化
var array:[String] = ["データ1", "データ2"]
var array = ["データ1", "データ2"]
```

## Dictionaryの初期化
Dictionaryの初期化は以下の構文で行えます。

```swift
// 空で初期化
let array:[String: String] = Dictionary()
let array:[String: String] = [:]
let array:[String: String] = [String: String]()
let array = [String: String]()

// データを入れて初期化
let array:[String: String] = ["Key1": "データ1", "Key2": "データ2"]
let array = ["Key1": "データ1", "Key2": "データ2"]
```

ArrayもDictionaryも初期化する方法がいくつか用意されているので、お好みで使用してください。

### たまにコンパイルエラーが発生する。
なぜかわからないが以下の様なクラス内のEnumを以下の様に生成するとコンパイルエラーが発生する。

```swift
let array = [ObjectClass.AnyEnum]()
```

この場合は諦めて以下の書き方で対応する。

```swift
let array:[ObjectClass.AnyEnum] = []
```

これ、Swiftのバグなんじゃないかな・・・？

## Arrayの存在確認
SwiftのArrayには`contains`関数が無い。
なので、Arrayに存在するかチェックするためには以下のように行う。

```swift
contains(["Test1", "Test2"], "Test1")    // true
```

知らなかったが`contains`は`Swift.contains`と書いてもコンパイルが通る。
ジャンプで飛べばわかるが、Swiftファイルの中にはInt64なども定義されてた。
このファイルがなんなのかは謎だが、Swiftの構文全てが定義されていそうな雰囲気のファイルだ。

## for文
僕はswiftでfor文を使う場合は大抵以下の使い方が多いです。

```swift
let array = ["データ1", "データ2"]
for str in array {
    print("\(str)")
}
```

swiftは配列に対してmap関数は用意されているが、each関数がないのでこの形を使うことがほとんどです。
（each関数があったとしてもswiftの場合はブロック構文はキャプチャーされるため、やはりfor文を使うケースの方が多いでしょう。）

しかし、たまにrubyでいうeach_with_indexを使いたくなります。

```rb
array = ["データ1", "データ2"]
array.each_with_index { |str, index|
    p "#{index}:#{str}"
}
```

これをSwiftで行う場合は以下のように書くとできます。

```swift
let array = ["データ1", "データ2"]
for (index, str) in enumerate(array) {
    print("\(index):\(str)")
}
```

気がついたら追記していきます。


P.S.
やはりSwiftは面白い。
今まではRubyが最強に気持ちいい言語だったけど、Swiftを知ってからSwiftの気持ちよさに酔いしれる・・・。
もう少しコード補完が早く、強くなってくれると嬉しいのでこの辺りはxCodeに頑張って欲しいw