`var foo: Type!` と`var foo: Type?` の違い


Swiftの勉強中に`var cellSize: CGFloat!` という記述が出てきました。

swiftではOptional型以外は値としてnilを取れないので、Optionalに変換してるのだと思うのですが
別の場所ではOptional型の宣言には`?`をつけると出ていました。

試しに`CGFloat!`を`CGFloat?`に置き換えてみたのですが、すぐにはエラーがでないようです。

この2つの表現にはどのような違いがあるのでしょうか？




## `?` と `!` の主な違い

`?` で作られた変数型は、Optional な値として扱われます。実質は `Optional<Type>`
型になります。これは質問内容の認識で合っています。

`!` で作られた値は、暗黙的にアンラップされる Optional な値 ( implicitly unwrapped optionals )
となります。実質は、 `ImplicitlyUnwrappedOptional<Type>`
型になっており、メソッドコールや、値参照がまるでラップされていないかのように、`nil` チェックなしでできるようになっています。

[code]

    var cellSize: CGFloat? = <初期化文>; // cellSize は、 Optional<CGFloat> 型
    println(cellSize!);                 // 強引に値をアンラップした
    cellSize!.getSummation() // 強引にアンラップしてメソッドを呼び出した (RuntimeError の危険あり)
    cellSize?.getSummation() // nil であれば返り値は Optinal で返る 
    if (let size = cellSize) {  // nil チェックを含んだアンラップ
        // nil ではなかった場合の処理
    }
    
    var cellSize: CGFloat! = <初期化文>; // cellSize は、 Optional<CGFloat> 型です
    println(cellSize);      // 強引に値をアンラップした
    cellSize.getSummation() // 強引にアンラップしてメソッドを呼び出した (RuntimeError の危険あり)
    
[/code]

## 使用用途はどう違うのか

では、使用用途としての違いってなんでしょうか。`!` は `nil` チェックをしなくても済むので、利用するのが楽に見えます。ただし、もちろん欠点として
保持値が `nil` であれば `RuntimeError` が発生する危険が残ります。( Optional にするけど、 `nil`
チェックするのは自由ですよ、ということはチェック抜けを誘発する。) ですので、 `nil`
チェックを強制する手段があるのに、それを潜り抜ける危険がある記法である 「 **`!` を普段から使うべきではなく、いつも `?` を使うのが良い**」
です。

質問で書かれたように、「Swift では Optional 型以外は値として `nil` をとれない」ということを理解されていると思います。`!`
を使うと見た目は `nil` を初期値として許容したような変数となります。ですので、例えば、「 **普段は絶対に`nil`
にならないが、オブジェクトの初期化順でどうしても初期値が `nil` でなければならない場合に `!` を使用する**」とよいでしょう。

参考: [Swift Programming Language
Guide](https://developer.apple.com/library/mac/documentation/Swift/Conceptual/Swift_Programming_Language/OptionalChaining.html#//apple_ref/doc/uid/TP40014097-CH21-XID_368)




## `?` と `!` の主な違い

`?` で作られた変数型は、Optional な値として扱われます。実質は `Optional<Type>`
型になります。これは質問内容の認識で合っています。

`!` で作られた値は、暗黙的にアンラップされる Optional な値 ( implicitly unwrapped optionals )
となります。実質は、 `ImplicitlyUnwrappedOptional<Type>`
型になっており、メソッドコールや、値参照がまるでラップされていないかのように、`nil` チェックなしでできるようになっています。

[code]

    var cellSize: CGFloat? = <初期化文>; // cellSize は、 Optional<CGFloat> 型
    println(cellSize!);                 // 強引に値をアンラップした
    cellSize!.getSummation() // 強引にアンラップしてメソッドを呼び出した (RuntimeError の危険あり)
    cellSize?.getSummation() // nil であれば返り値は Optinal で返る 
    if (let size = cellSize) {  // nil チェックを含んだアンラップ
        // nil ではなかった場合の処理
    }
    
    var cellSize: CGFloat! = <初期化文>; // cellSize は、 Optional<CGFloat> 型です
    println(cellSize);      // 強引に値をアンラップした
    cellSize.getSummation() // 強引にアンラップしてメソッドを呼び出した (RuntimeError の危険あり)
    
[/code]

## 使用用途はどう違うのか

では、使用用途としての違いってなんでしょうか。`!` は `nil` チェックをしなくても済むので、利用するのが楽に見えます。ただし、もちろん欠点として
保持値が `nil` であれば `RuntimeError` が発生する危険が残ります。( Optional にするけど、 `nil`
チェックするのは自由ですよ、ということはチェック抜けを誘発する。) ですので、 `nil`
チェックを強制する手段があるのに、それを潜り抜ける危険がある記法である 「 **`!` を普段から使うべきではなく、いつも `?` を使うのが良い**」
です。

質問で書かれたように、「Swift では Optional 型以外は値として `nil` をとれない」ということを理解されていると思います。`!`
を使うと見た目は `nil` を初期値として許容したような変数となります。ですので、例えば、「 **普段は絶対に`nil`
にならないが、オブジェクトの初期化順でどうしても初期値が `nil` でなければならない場合に `!` を使用する**」とよいでしょう。

参考: [Swift Programming Language
Guide](https://developer.apple.com/library/mac/documentation/Swift/Conceptual/Swift_Programming_Language/OptionalChaining.html#//apple_ref/doc/uid/TP40014097-CH21-XID_368)

