こんばんは。Androidエンジニアの星川 (id:oboenikui) です。
本日 (2018/12/15) のJJUG CCCにて、エムスリーはブースを出展しました。
そちらでKotlin Puzzlerを出題しましたので、問題の解説をいたします!
ルームK ブースエリアにて、Kotlin Puzzlersを開催しております!
— M3 エンジニア公式 (@m3_engineering) 2018年12月15日
来場者の方は是非チャレンジしてみて下さい! #jjug_ccc pic.twitter.com/R2xM5AFIMt
(掲示にはKotlin Puzzlersと書きましたが、1問でした)
問題文
fun foo(cb: (() -> Unit) -> Unit = {}) = cb
と定義される時、変数a
の型がUnit
になるものを全て選べ。
①
val bar = foo {} val a = bar {}
②
val a = foo() {}
③
val a = foo {}({})
④
val a = foo({}) {}
皆さんの解答
皆さんが答えだと思う選択肢にシールを貼っていただきました。
②, ③ が多いですね!正解は……?
①, ③ でした!!!正解された方々おめでとうございます!!!
他の選択肢については、
②は、 (() -> Unit) -> Unit
型
④は、文法エラー
でした。
解説
まずメソッドfoo
について。foo
は(() -> Unit) -> Unit
型の引数を取り、そのまま(() -> Unit) -> Unit
型を返すメソッドです。デフォルトの値{}
も指定されています(が、実はひっかけで今回は関係ありません)。
Kotlinでは、関数の最後の引数の型がラムダだった場合、括弧の外に移動できます。また、ラムダが関数で唯一の引数だった場合は空の括弧も省略できます。更に、ラムダ内の引数が1つだった場合も引数を省略できます。
即ち、問題の関数は以下のような呼び出しが可能です。
val bar = foo {}
このときのbar
の型は(() -> Unit) -> Unit
です。
以下、個々の選択肢について。
① → ○
関数型の変数は、通常の関数と同じ形式で実行できます。bar
の型は(() -> Unit) -> Unit
なので、
val a = bar {}
と書くことができ、その型はUnit
です。
② → ✗
ラムダ内の引数も1つだった場合、省略できますが、書いても実行結果は変わりません。そのためaの型は(() -> Unit) -> Unit
です。
③ → ○
関数型が返ってくる場合、直接引数を渡して実行することも可能です。
1 と同じなので、a
はUnit
となります。
④ → ✗
この呼び出しでは、2つめのラムダの引数を渡しているのと同義になります。
2つの引数を取るfoo
という名前のメソッドは定義されていませんので、文法エラーとなります。
…解説は以上です!
もしかするとどこかで別の問題を出題するかも……?次回をお楽しみに!!
We are hiring!!
エムスリーでは、共に医療 × テクノロジーの未来を切り拓いてくれる仲間を募集中です。
問題が解けた方も、解けなかった方も、興味を持っていただけたら、カジュアル面談をいつでもやっていますのでぜひ遊びに来てください!!