エムスリーテックブログ

エムスリー(m3)のエンジニア・開発メンバーによる技術ブログです

JJUG CCC 2018 Fall Kotlin Puzzler 解説

こんばんは。Androidエンジニアの星川 (id:oboenikui) です。

本日 (2018/12/15) のJJUG CCCにて、エムスリーはブースを出展しました。

そちらでKotlin Puzzlerを出題しましたので、問題の解説をいたします!

(掲示には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({}) {}

皆さんの解答

皆さんが答えだと思う選択肢にシールを貼っていただきました。

f:id:oboenikui:20181215220221p:plain

②, ③ が多いですね!正解は……?

 

 

   

   

   

   

 

①, ③ でした!!!正解された方々おめでとうございます!!!

他の選択肢については、

②は、 (() -> 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 と同じなので、aUnitとなります。

④ → ✗

この呼び出しでは、2つめのラムダの引数を渡しているのと同義になります。

2つの引数を取るfooという名前のメソッドは定義されていませんので、文法エラーとなります。

…解説は以上です!

もしかするとどこかで別の問題を出題するかも……?次回をお楽しみに!!

We are hiring!!

エムスリーでは、共に医療 × テクノロジーの未来を切り拓いてくれる仲間を募集中です。

問題が解けた方も、解けなかった方も、興味を持っていただけたら、カジュアル面談をいつでもやっていますのでぜひ遊びに来てください!!

カジュアル面談の応募はこちら