📑
Kotlin脳内ランタイムクイズ(解答編)
Kotlin 問題集
この記事は Kotlin Fest 2024 のログラスブースでのクイズ企画の解答です。
出力は?
- null
- 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
main()実行時の出力は?
- fizz => buzz => 8 => fizzbuzz
- fizzbuzz => fizzbuzz => 8 => fizzbuzz
- 8
- 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
解説
This includes replacing all
if
expressions with
correspondingwhen
expressions, convertingfor
loops into blocks withiterator
variable declaration andwhile
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 という出力になります。
戻り値は?
- 例外が投げられる
- Unit
- Nothing
fun test() {
throw return
}
答え
2 の Unit が return されます
- throw の評価 → return の評価と解釈されるため、最後の return でブロックを抜けて Unit が return されます。
出力される順番は?
- 3 ⇒ 2 ⇒ 4 ⇒ 1
- 3 ⇒ 4 ⇒ 2 ⇒ 1
- 2 ⇒ 1 ⇒ 3 ⇒ 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)
}
}
出力は?
- 32
- 64
- 128
- 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
}
Discussion