70
29

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Voidを返す関数内でのreturnは気をつけた方がいい

Last updated at Posted at 2020-01-10

追記

  • Warningは正しかったです。

問題

  • 以下はどういう出力になるでしょうか。
func foo() {
  print(#function)
  return // ← この後の処理は一旦無視したいからreturnしておこう

  bar()
}

func bar() {
  print(#function)
}

答え

  • bar() も実行され出力されます。
foo()
bar()

理由

  • 構文上、returnの後の改行は無視されて解釈されるので return bar() となり、 bar() が実行されるため。
func foo() { // 暗黙的に戻り値はVoidを返す関数
  print(#function)
  return
   
  bar() // return bar() と解釈されるのでbar()は実行される
}

func bar() { // 暗黙的に戻り値はVoidを返す関数
  print(#function)
}
  • 以下が構文上許されているのと同じ意味です。
func baz() -> Int {
  return
    
    
  1
}

解決方法

  • セミコロンをつけます。
func foo() { // 暗黙的に戻り値はVoidを返す関数
  print(#function)
  return; // セミコロンをつければ `return ()` として解釈される
   
  bar() // 実行されない
}

バグ?

追記

  • あれ!Warningの内容が Expression following 'return' is treated as an argument of the 'return' ('return' に続く式は'return'の引数として扱われます) だ!よく一時的な早期returnで遭遇する Code after 'return' will never be executed と勘違いしていた…なのでWarningはあっていますね。

  • return 後の改行が無視されて解釈されるのは言語仕様としては正しいと思いますが、Warningで Expression following 'return' is treated as an argument of the 'return' が表示されるのはバグだと思われます。 あってる🙇‍♂️
スクリーンショット 2020-01-10 14.08.59.png
  • ちなみにIntの方も表示された…。
スクリーンショット 2020-01-10 14.21.11.png

まとめ

  • Voidを返す関数でreturnを使う場合はセミコロンをつけないと意図しない挙動になる可能性がある。 追記: Warningはちゃんと読みましょう。。。
  • DevSapにて return が無視されるんだけどって話題が出て、僕自身も遭遇した経験があるので今回調査してみました。今までは差分コンパイル時のバグかな?って思って return は避けてコメントアウトするようにしていたのですが、今回やっと原因がわかりました。これは罠すぎる。。。
70
29
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
70
29

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?