質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

3回答

13937閲覧

Swift の if 文で let 変数に代入して nil 判定する方法について

odorry

総合スコア54

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

4クリップ

投稿2014/11/14 20:36

後述するコードの挙動が納得できません。
※特に、挙動確認パターン3と4が納得できません

【ドキュメントにこう書いてあるよ】、とか、【◯◯という理由でそのような挙動になるのだと思います】、と言ったご意見等をいただけると助かります。

自分の中では、【そういう仕様であるということを受け入れる】という結論にしています。

問題のコードはこちらです。

lang

1var nilValue1: String? = nil 2 3// 挙動確認パターン1 4if let hoge = nilValue1 { // " hoge は nil です。" 5 println(" hoge は nil ではありません。") 6} else { 7 println(" hoge は nil です。") 8} 9 10// 挙動確認パターン2 11if let hoge: String = nilValue1 { // " hoge は nil です。" 12 println(" hoge は nil ではありません。") 13} else { 14 println(" hoge は nil です。") 15} 16 17// 挙動確認パターン3 18if let hoge: String! = nilValue1 { // " hoge は nil ではありません。" 19 println(" hoge は nil ではありません。") 20} else { 21 println(" hoge は nil です。") 22} 23 24// 挙動確認パターン4 25if let hoge: String? = nilValue1 { // " hoge は nil ではありません。" 26 println(" hoge は nil ではありません。") 27} else { 28 println(" hoge は nil です。") 29}

挙動確認パターン3と4も【hoge は nil です】と表示されることを期待していましたが、実際の挙動は違っていました。

let 宣言した hoge 変数に Optional な型を書いたことによって、
その if 文の行ではアンラップされないからなのでは?と推測しています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

Optional型のunwrapについて知ると良いかもしれません。
この記事によくまとまっていて私は腹に落ちたので参考までに。

[Swift] Optional 型についてのまとめ Ver2

投稿2014/12/24 00:53

iyuichi

総合スコア39

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

パターン1と2はオプショナルバインディング(右辺に値があればアンラップ)ですが
3と4はただの代入なので、挙動としては自然であるように思います。

イメージ的には以下のような感じでしょうか(コンパイルは通りませんが)。

lang

1let hoge:String? = nil 2 3// pattern1 4if (let a = hoge!) == true { 5} 6// pattern2 7if (let b:String = hoge!) == true { 8} 9// pattern3 10if (let c:String! = hoge) == true { 11} 12// pattern4 13if (let d:String? = hoge) == true { 14} 15

投稿2014/11/28 07:19

bluedome

総合スコア57

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

odorry

2014/11/28 15:44

ご回答ありがとうございます。 全て共通して、【左辺に代入した上で、nil かどうかチェックする】ということをやってくれるのがオプショナルバインディングだと思っていましたが、そういうわけではないのですね。 認識を改めます。
guest

0

不思議な挙動ですね。
たしかに、結果的にアンラップが発生したかどうかで判定してるように見えます。

この「自作if-let」が参考になるかもです。
Writing your own Swift "if let"

Swift

1func ifLet<T>(value: T?, then: T -> (), else elseFunc: () -> ()) { 2 switch value { 3 case .some(let x): then(x) 4 case .none: elseFunc() 5 } 6}

上記処理だと、パターン1, 2 の場合、TがStringになると思いますが、パターン3, 4 の場合 TがOptionalになると思われ、そうするとswitch文で型が一致するので .Some の方に入ってしまうのではないでしょうか。

投稿2016/08/14 01:35

YokemuraTakeshi

総合スコア297

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問