算譜王におれはなる!!!!

偏りはあると思うけど情報技術全般についてマイペースに書くよ。

第2回関西Kotlin勉強会で発表してきたよ〜 #ashiyakt

f:id:ngsw_taro:20150924221632j:plain

9/19に関西Kotlin勉強会に参加すべく兵庫は芦屋へ行ってきました。

connpass.com

私の発表資料はこちら↓

前回同様いい意味でゆる〜い雰囲気で、発表後の質疑応答も活発だったし、余った時間であーだこーだ議論するのも楽しかったです。

@takuji31さんの飛び入りLTもありました。

ちなみに冒頭の写真は@yy_yankさんの発表資料です。

懇親会も盛り上がりました!

9/20にはみんなでセルフ祭に行きました。 関西Kotlin勉強会に行くついでにセルフ祭、定番になりそう。

Kotlin M13で追加されたsealed class

Kotlin マイルストーン13 がリリースされました!

blog.jetbrains.com

lateinit修飾子については↓の記事をば。

Kotlin M13で追加されたlateinit試してみた - 算譜王におれはなる!!!!

sealed class

クラスに付けられるsealed修飾子が追加されました。 一言で言うと、クラスの継承を制限するための修飾子です。 sealedが付いたクラスを継承するにはある条件を満たす必要があるということです。 そういう意味でScalasealedと似ていてC#のそれとは異なります。

肝心のsealed classを継承するための条件ですが、現時点ではsealed classにネストされたクラスであることです。

sealed class A {
  class B: A()
}

class C: A() // これはダメ

そのうち、この制限を緩和して同一ソースファイル内での継承も許可するそうです。

さて、このsealed classですが何の役に立つのかと言うと、リリースノート内でAlgebraic Data Types(代数的データ型)というキーワードが登場しています。 例えば列挙型をenum classではなくsealed classとそのサブクラスで表現可能です。

sealed class Color {
  object Red:   Color()
  object Green: Color()
  object Blue:  Color()
}

val name = when(color) {
  Color.Red   -> "赤"
  Color.Green -> "緑"
  Color.Blue  -> "青"
}

when式の分岐でelseがないことに注目してください。 Colorsealed classとして定義されており、他の場所でそのサブクラスが定義されないことを保証します。 そのためwhen式の分岐でRedGreenBlueすべての場合が考慮されていることをコンパイラは知っているのでelseが不要になります。 Coloropen classとして定義された場合には、他の場所でもそのサブクラスが定義される可能性があるのでコンパイラはwhen式にelseを要求します。

次に、sealed classを使って直和型を表現してみます。

import Option.*

sealed class Option<out T> {
  class Some<T>(val value: T): Option<T>()
  object None: Option<Nothing>()
}

val name = when (userOption) {
  is Some<User> -> userOption.value.name
  is None       -> "null"
}

便利ですね〜。 ちなみにインタフェースにはsealedを付けられないみたいです。

Kotlin M13で追加されたlateinit試してみた

Kotlin マイルストーン13 がリリースされました!

blog.jetbrains.com

その中で追加されたlateinitというプロパティにつける修飾子が便利そう。 プロパティの初期化を先延ばしにできるので既存のフレームワークにインジェクトしてもらえるって寸法です。

「プロパティの初期化の先延ばし」っていうとDelegated propertyを思い出すけど、これには問題があったのでした。。

ということでlateinitを試してみました。

import com.google.inject.Guice
import javax.inject.Inject
import kotlin.properties.Delegates

class Greeter {
  fun greet() {
    println("Hello")
  }
}

class Client {
  @Inject
  lateinit val greeter1: Greeter

  @Inject
  val greeter2: Greeter by Delegates.notNull()
}

fun main(args: Array<String>) {
  val injector = Guice.createInjector()
  val client = injector.getInstance(Client::class.java)
  client.greeter1.greet() //=> Hello
  client.greeter2.greet() // IllegalStateException thrown
}

Google Guiceでインジェクトしています。 lateinitが付いているgreeter1は見事インジェクトされています!しかし、Delegates.notNull()をつけているgreeter2はインジェクトされておらずgreet()呼び出し時に初期化が済んでないよと例外が投げられてしまいました。

そのほかの変更点についてはまた後ほど。

ちなみにこれならいける

var greeter2: Greeter by Delegates.notNull()
  @Inject set

第3回かわいいKotlin勉強会を開催しました #jkug

kotlin.doorkeeper.jp

開催しました!!!

第3回です!!

44名の方にご来場いただきました。 申し込み自体はキャンセル混みで86名です。 すごい人気です。

会場をご提供してくださいましたドリコム様(@sue445さん)、 運営スタッフの@yy_yankさんにこの場をお借りして感謝申し上げます。

発表資料

Kotlinらしいコード (私)

Server Side Kotlin (@yy_yankさん)

個人開発AndroidアプリをKotlinにガチ移行してみた話 (@kiriminさん)

Kotlin as an AltJS (@mike_neckさん)

(あやぴーさん)

普段C#使っている僕から見た、Kotlin (@RyotaMurohoshiさん)