📑

Kotlin脳内ランタイムクイズ(解答編)

2024/06/26に公開

Kotlin 問題集

この記事は Kotlin Fest 2024 のログラスブースでのクイズ企画の解答です。
https://www.kotlinfest.dev/
https://zenn.dev/loglass/articles/kotlin-question
https://x.com/LoglassPrdTeam/status/1804404958990872792

出力は?

  1. null
  2. NullPointerException が throw される
fun main() {
    print(null.toString())
}

答え

  • 1 の null
  • kotlin 標準の toString は Any?の拡張関数として定義されています
/**
 * Returns a string representation of the object. Can be called with a null receiver, in which case
 * it returns the string "null".
 */
public fun Any?.toString(): String

https://pl.kotl.in/agFpkCWf2?theme=darcula

main()実行時の出力は?

  1. fizz => buzz => 8 => fizzbuzz
  2. fizzbuzz => fizzbuzz => 8 => fizzbuzz
  3. 8
  4. buzz => 8
fun main() {
    fizzBuzz(3)
    fizzBuzz(5)
    fizzBuzz(8)
    fizzBuzz(15)
}

fun fizzBuzz(num: Int) {
    if (num % (3 * 5) == 0) {
        "fizzbuzz"
    } else if (num % 3 == 0) {
        "fizz"
    } else if (num % 5 == 0) {
        "buzz"
    } else {
        num
    }.let(::println)
}

答え

4 の buzz => 8

https://pl.kotl.in/IRBc2ZZZ2?theme=darcula

解説

https://github.com/JetBrains/kotlin/commit/d1335d3f44d3b93da62efd3e4ff44c6a0b9223b6#diff-9f2fbb64437263c2987cd82c7a0b3cd5ebcb4f6104c6bfa5b8dd7613cb5ba19bR13-R17

This includes replacing all if expressions with
corresponding when expressions, converting for loops into blocks with iterator variable declaration and while loop, and similar.

とあり、if 式は when 式に変換される旨が記載されています。
問題の式は下記のように変換されます。

when {
	num % (3 * 5) == 0 -> "fizzbuzz"
	else -> when {
		num % 3 == 0 -> "fizz"
		else -> when {
		  num % 5 == 0 -> "buzz"
		  else -> num
		}.let(::println)
	}
}

let が最後の else のブロックにしか掛かっていないため、buzz => 8 という出力になります。

戻り値は?

  1. 例外が投げられる
  2. Unit
  3. Nothing
fun test() {
    throw return
}

答え

2 の Unit が return されます

  • throw の評価 → return の評価と解釈されるため、最後の return でブロックを抜けて Unit が return されます。

https://pl.kotl.in/RCuNrOe1H?theme=darcula

出力される順番は?

  1. 3 ⇒ 2 ⇒ 4 ⇒ 1
  2. 3 ⇒ 4 ⇒ 2 ⇒ 1
  3. 2 ⇒ 1 ⇒ 3 ⇒ 4
  4. 2 ⇒ 3 ⇒ 4 ⇒ 1
fun main() {
    runBlocking {
        async {
            runBlocking {
                async {
                    delay(300)
                    println(1)
                }
                listOf(
                    async { delay(100) },
                    async { delay(100) },
                    async { delay(100) },
                ).awaitAll()
                println(2)
            }
        }
        println(3)
        delay(200)
        println(4)
    }
}

答え

1 の 3 ⇒ 2 ⇒ 4 ⇒ 1

fun main() {
    runBlocking {
        async {
            runBlocking {
                // 4. 300ms後に1が出力される
                async {
                    delay(300)
                    println(1)
                }

                // 2. 100msがすべて非同期で実行されるので、実質100ms程度(オーバーヘッド除く)で2が出力される
                listOf(
                    async { delay(100) },
                    async { delay(100) },
                    async { delay(100) },
                ).awaitAll()
                println(2)
            }
        }
        // 1. delayが一切かからないので3が出力される
        println(3)
        delay(200)
        // 3. 200ms後に4が出力される
        println(4)
    }
}

https://pl.kotl.in/jwSyyte54?theme=darcula

出力は?

  1. 32
  2. 64
  3. 128
  4. 256
fun main() {
    2.test()
}

fun Int.test() {
    2.let {
        square(it) * square(this).run {
            this.also {
                (square(it) * this).apply {
                    square(this)
                }
            }.let(::square)
        }
    }.let(::println)
}

private fun square(n: Int): Int {
    return n * n
}

答え

2 の 64

fun main() {
    2.test()
}

fun Int.test() {
    2.let {
        // square(it)=4, square(this)=4
        square(it) * square(this).run {
            // alsoやapplyは副作用を起こすだけで、戻り値はレシーバになるので、alsoは4が返却される
            this.also {
                (square(it) * this).apply {
                    square(this)
                }
            }.let(::square) // alsoの戻り値をsquareしているので16になる
        }
    }.let(::println) // 4 * 16 = 64
}

private fun square(n: Int): Int {
    return n * n
}

https://pl.kotl.in/IjIb1m3UE?theme=darcula

GitHubで編集を提案
株式会社ログラス テックブログ

Discussion