↑クリックして拡大
↑クリックして拡大
↑クリックして拡大
↑クリックして拡大

頭痛が減ったので共有です!

rebuild.fmを応援しています!

HOME > クエスチョンマークとビックリマーク

クエスチョンマークとビックリマーク

Swiftを開発するようになって頻繁に目にする変数宣言時のクエスチョンマークやビックリマークの意味がわからなかったので調査します。こちらオプショナル型(optional value)との名称があるようです。

サンプル画像


参考: Swiftことはじめ:String?のクエスチョンマークって何?
参考: 【Swift入門】Optional型 (?, !) をまとめてみた
参考: Swift ( beta7 )での設計方針について 〜 Optionalとの付き合い方 〜 [追記あり]
参考: どこよりも分かりやすいSwiftの"?"と"!" <ー★オススメ!

'?'のクエスチョンマーク

以下の違いはわかりますでしょうか?


//片方だけクエスチョンマーク付き
var test1 = "hogehoge";
var test2? = "hogehoge";

こちら、どうやら?をつけないとnilが代入できないようです。(nilは標準では追加不可になり厳格になった)



var test1 = "hogehoge";
test1 = nil;//エラー!!!

var test2? = "hogehoge";
test2 = nil;//問題なし

'!'のビックリマーク

さて、では吃驚マークはどう扱うのでしょうか?これは?マークの付随品みたいなものです。?があってこその記号だと覚えてください。 以下のコードはどう処理されると思いますか?


    //クエスチョン付きInt型
    var questionInt:Int? = 123;

    //Intを引数にもつ関数
    func test(value:Int){
        println(value);
    }
    
    test(questionInt);

こちらですが、コンパイルエラーとなります。Int!型にIntを入れたので


    test(questionInt);
    

この箇所がクエスチョンマークがついているエラーになります。これをどうにかして処理させたい時に以下のように記載します。


    test(questionInt!);
    

するとエラーなく処理されます。

以下の様に省略しないで記載することも可能です。同じ意味です。

//省略タイプ
var questionInt:Int? = 123;
    
//通常タイプ
var questionInt:Optional<Int> = 123;

注意(2014/12/17追記)

Optional型の省略形とアンラップの !, ? は別物なので注意です。少しややこしいですが、Optional型の宣言には?と!の2種類どちらも利用できます。?は上述の通りですが、!は少し挙動が違います、以下のコードをご確認ください。

(?) = Optional型

//(?)Optional省略タイプ
var optionalInt:Int? = 123;
var optionalInt:Optional<Int> = 123;と同じ

var nilobj = nil;
optionalInt = nilobj! //(!)をつけてUnwrapしないとエラー

(!) = Implicitly Unwrapped Optional型

//(!)Implicitly Unwrapped Optional省略タイプ
var optionalInt:Int! = 123;
var unwrappedOptionalInt:ImplicitlyUnwrappedOptional<Int> = 123;と同じ

var nilobj = nil;
unwrappedOptionalInt = nilobj //(!)をつけなくてもOK!自動でUnwrap

まとめ

どうやらこの複雑に見える宣言方法ですが、nilによるエラーを極力下げる為のようです。たしかにobjective-cではnil関連で何度もクラッシュしていましたので、、、、、、、コンパイル時にnilが使われていないことを標準の変数で明確にさせるための策のようで、その他言語でも採用されてきているnull対策のようでした。

忘れやすいので、私はこう覚えています

??????????変数??????????? - ?で変数をラッピング。
これでnil厳格なコンパイル君には気づかれない

??????????変数+nil??????????? コンパイル君(見てるけど、?で見えない)

!の通行手形をもっている変数だけは?を通過できる。!の他の用途もあるので一概には言えませんが、、、

追記(2015/01/25)

unexpectedly found nil while unwrapping an Optional value(Optional型の値をアンラップした時に予期せぬnilを見つけました)のエラーに対応する記事を以下に追加しました。 よろしければ合わせてご一読くださいませ
unexpectedly found nil while unwrapping an Optional valueの対応

↓こんな記事もありますよ!


2021-05-14 14:21:41

WatchOSのwatchconnectivityのFiletransferの落とし穴。と、避け方。

AppleWatch 実機だと成功するんだけど、シュミレーターだと失敗するという、、、 昔作成してた時は成功してたのになーと思って調べると、どうやら昔は成功してたみたい。watchOS6以降は...

2021-05-06 14:04:37

LINEのアニメーションスタンプ制作の落とし穴、、、失敗談

ゴールデンウィークにLINEスタンプを作成してみました。 作り切って申請も通したんですが、意図したアニメーションと違う、、、、 LINEクリエーターの画面だと、アニメーションのプレビュー...

2021-05-01 18:05:35

久しぶりのAdmobをobjective-cに実装。コンパイルエラーだらけ。バーミッション不具合でエミュレータにインスコできない。

忘れないようにメモ エミュレータにアプリをインストールする際にパーミッション系のエラーがでた時、また、iphone実機にインストールする際にも権限系のエラーが出る場合。 ターゲット→ex...
このエントリーをはてなブックマークに追加
右側のFacebookのLikeをクリック頂けると記事更新の際に通知されますので宜しければご利用下さい!