kdnakt blog

hello there.

会社でKotlin勉強会(第21回)を開催した

今週は第21回を開催しました。

 

前回の様子はコチラ↓

kdnakt.hatenablog.com

 

 

[第21回の様子]

2020/07/08に第21回を開催した。

 

参加メンバーは自分を含めて3人。前回、前々回はたしか同じメンバーだったが、そのときとは違うメンバーが参加している。隔週参加みたいな感じでも、自分がつらつらとKotlinの勉強をするのに付き合ってくれる経験豊富なメンバーが何人もいてくれてとても心強い。

 

勉強会本編の内容としては、Learn Kotlin by Exampleの第8章 Productivity BoostersのDestructuring DeclarationsSmart Castsを進めて第8章を完了した。

第9章 Kotlin/JSについては、まあKotlinでJSを書くなんてそうそう必要ないだろうからということで切り捨てることにした。というわけで、今回で2月から続く勉強会に一区切りつくことになる。来週からは同じサイト上で実施できる練習問題集Kotlin Koansを進めていく予定だ。

 

前々回、前回と、Exampleをみながら直接コードを実行することができない状態が続いていたが、今回はLearn Kotlin by Exampleのサイト上でコードを実行する機能が復活していた。ありがたや。

play.kotlinlang.org

 

[学んだことや疑問点]

  • Destructuring Declarations
    • 分解して宣言する、ということらしい
    • C++でいうところの構造化束縛に当たると教えてもらった
    • JavaScriptでいうところの分割代入と似たような概念だと理解した
    • こういうのはプログラミング言語ごとに呼び名が違うらしい。概念揃えてくれればいいのに。大変。
    • いくつか試したところ分割後の要素数が多い場合に分解宣言をするとArrayIndexOutOfBoundsExceptionが発生した
val (x1, y1, z1) = arrayOf(5, 10, 15) // 分解前後が同じ数なら当然OK 
val (x2, y2, z2) = arrayOf(5, 10, 15, 20) // 分解前の要素数が多いのはOK
val (x3, y3, z3) = arrayOf(5, 10) // 分解後の要素数が多いのはNG
// Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2
    • Mapのキーと値を分解できるのは割と便利そうだと感じた
val map = mapOf("Alice" to 21, "Bob" to 25)
for ((name, age) in map) {
    println("$name is $age years old")
}
// Alice is 21 years old
// Bob is 25 years old
    • Dataクラスのフィールドも、宣言されている順番どおりに分解できる
    • このとき利用されるのがKotlin勉強会(第7回)で登場したDataクラスのcomponentN()メソッドということらしく、独自のクラスにcomponentN()メソッドを実装すると分解宣言ができるようになるらしい
data class User(val username: String, val email: String)

fun main() {
    val user = User("Mary", "mary@somewhere.com")
    val (username, _) = user
    println(username == user.component1()) // true
}
  • Smart Casts
    • Hoge?のようなnullableな型を宣言していても、nullチェックを実行したあとはHogeとしてnon-nullableな型扱いしてくれるのがSmart Castらしい
    • たしかにKotlin勉強会(第2回)でKotlinのNullについて学んだ際に、以下のようなコードが登場していた(Null Safety
    • Smart Castを知らなければ、maybeStringはnullableなのでmaybeString.length > 0の箇所はmaybeString?.length > 0であるべき、と思うのが自然だったかも。気がつかなかった……。
fun describeString(maybeString: String?): String {
    if (maybeString != null && maybeString.length > 0) {
        return "String of length ${maybeString.length}"
    } else {
        return "Empty or null string"
    }
}
    • isで型判定をしたあとはそのままJavaでいうダウンキャストもできるらしい
    • Java 14にプレビュー機能として登場したinstanceofによるパターンマッチングと似ている
val date: ChronoLocalDate? = LocalDate.now()
if (date is LocalDate) {
    val month = date.monthValue
    println(month) // 現在が7月であれば7が表示される
}
val month2 = date.monthValue
// Unresolved reference: monthValue
// monthValueはChronoLocalDateの下位クラスであるLocalDateにしか存在しないフィールドなのでエラー
// Java 13の場合
var o = "Hello World!";
if (o instanceof String) {
    String s = (String) o;
    System.out.println(s.length()); // 12
}

// Java 14の場合
var o = "Hello World!";
if (o instanceof String s) { // ここで変数割り当てができる
    System.out.println(s.length()); // 12
}

 

[まとめ]

今回でLearn Kotlin by Exampleの勉強は終了。やったー!

約半年間つきあってくれたみなさまありがとうございます!

 

次回からは、これまで学んできたことを生かしつつ練習問題集Kotlin Koansを進めていくぞ!