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

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

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

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

Q&A

解決済

3回答

1918閲覧

defer文が実行されない

Blue0999

総合スコア148

Swift

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

0グッド

0クリップ

投稿2016/03/24 04:39

参考書(詳解Swift改訂版)のコードで理解できないものがあったので質問させていただきます。
下記の関数doit()のdefer文なのですが引数に0を与えdoit()を実行すると二番目のdefer文が実行されません。説明には『実行が及んでないdefer文は実行されない』と書いてあるのですがこのdeferはif文のブロック外なので実行が及んでないの意味がわかりません。
func doit(a:Int) {
var n = 0
defer { print(1,n) }
if a == 0 { return }
defer { print(2, "oops") }
n = a
}

doit(0)

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

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

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

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

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

guest

回答3

0

if a == 0 { return }
にて return されています。
(それ以降の処理を行わず処理を終了する)
そのため2番目のdeferは実行されません

引数に0以外を入れれば、
if a == 0 { return }
でreturnされず、2番目のdeferが実行されます

投稿2016/03/24 04:55

Rumi_Igarashi

総合スコア47

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

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

Blue0999

2016/03/24 05:13 編集

ご回答ありがとうございます! return後処理は終了されるのですね。 deferはブロックの処理の最後に呼び出されるものなのでdeferは2つともif文で処理を終了した後に実行されると思うのですが…1つ目のdeferだけが実行されるのはなぜでしょうか?
Rumi_Igarashi

2016/03/24 05:24

returnされてしまった場合、以降のコードは読み込まれることはないため、 二番目のdeferは読み込まれすらしていません。
Blue0999

2016/03/24 06:36 編集

では最初のdeferはreturnの前なので呼び出され、二番目のdeferはreturn後なので評価すらされないという事でしょうか? deferはブロックの最後に呼び出されるのが原則だと思うのですが、returnがある場合は通常の順番通りに評価されるという事でしょうか? ------------------------------------------------------------------------------------------------------------- defer { print(a) } // 原則どおりdeferは最後に呼び出される var a = 1 ------------------------------------------------------------------------------------------------------------- var a = 1 return a // returnが先に呼び出される defer { print(a) } ------------------------------------------------------------------------------------------------------------- 質問が増えてしまって申し訳ありません。
AOKINAO

2016/03/24 06:49

 deferは、「deferに続くブロック内を、defer自信が含まれるブロックを抜ける時に実行するように『予約する』機能」なので、defer自信が実行されなければ、予約そのものがされません(「予約」という言葉は、説明用に使っただけで、swiftの用語ではないのでご注意ください)
guest

0

ベストアンサー

deferはブロックの最後に呼び出されるのが原則だと思うのですが

間違ってます。
deferの"中身が"ブロックの最後に呼び出されます。

雑に説明すると
defer{f}は「ブロックを抜けるときにfを行う」の登録作業です。
ですから、

swift

1return a // returnが先に呼び出される 2defer { print(a) }

と書けば、登録作業の前に抜けているので、print(a)は実行されません

投稿2016/03/24 06:44

ozwk

総合スコア13528

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

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

Blue0999

2016/03/24 06:55

ご回答ありがとうございます。わかりやすくとても納得できました! defer自体は登録作業なのでdeferは処理の順番通りに呼び出され、defer内の処理がブロックの最後に呼び出されるという事ですよね。
guest

0

実行が及んでいない のは、if文により、引数aが0の場合2番目のdeferまで実行が及んでいないという意図でしょう。

投稿2016/03/24 04:51

t_obara

総合スコア5488

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

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

Blue0999

2016/03/24 04:56

ご回答ありがとうございます! 教えていただいた事を参考にplaygroundでif分の条件をaが1だった場合に変更して試してみたらその通りでした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問