Eight事業部でEightのAndroid版の開発を担当している山本です。
2018年8月25日に行われた。Kotlin Fest 2018に行ってきました。
Sansan株式会社ではKotlin勉強会を2016年から行っており、私自身もKotlin入門までの助走読本の執筆に参加したり、Kotlin in Actionの翻訳に参加するなど、Kotlinとは深く関係してきたので、今回のイベントはとても楽しみにしていました。
また、Sansanは今回のKotlin Festにはスポンサーとして参加しました。スポンサーブースには、たくさんの方々にお越しいただきました。ありがとうございました。
最後はsansanさん!ブースではあのCMにちなんだゴルフボールなどを配布中!ゴルフをする方もしない方もぜひブースへ! #kotlinfest pic.twitter.com/ZcchR9N0Ow
— Kotlin Fest 2018 (@kotlin_fest) 2018年8月25日
セッションの資料の一覧はこちら
この中で自分が参加したセッションについてレポートしていきたいと思います。
オープニングセッション
オープニングセッションでは日本Kotlinユーザーグループ会長のたろうさんによる、これまでのKotlinの歩みの振り返りとKotlinのコミュニティ活動についての説明がありました。また、同じく日本Kotlinユーザーグループの藤原聖さんは、Kotlinの特徴や哲学、Kotlinを知るためのリソースについて紹介されていました。
#kotlinfest やってまーす pic.twitter.com/7QGrKvz4gl
— じゅんぺ (@boohbah) 2018年8月25日
そして、今回のテーマは「Kotlinを愛でる」です。 これは、自分も翻訳に参加させていただいた「Kotlin イン アクション」の第2部のタイトルで、原著では「Embracing Kotlin」となっており、翻訳時にこれをどう訳すのかについて熱く議論したことを思い出しました。
Kotlinもう一歩
発表者はYahoo!の森洋之さん。 Kotlinの型システムについての突っ込んだ話をされていました。
内容
- タイプとはなにか?
- タイプとサブタイプについて
- KotlinのタイプシステムではInt型はInt型のサブタイプでもありスーパータイプでもある
- Any型
- Nothing型
- nullableとnon-null
- Generics
- 上限境界
- 型引数とnullability
- Type Erasure
- 変位
- 不変、共変、反変
- Type Projection
勉強になったところ
不変、共変、反変
ジェネリクス型の変位についての説明がわかりやすくてよかったです。
変位とは、Genericsで型変数を定義するときに
クラスB
がクラスA
のサブタイプであるときに、Foo<B>
とFoo<A>
がどういう関係にあるかを指定するもので、
- invariant(不変)
- covariant(共変)
- contravariant(反変)
の3種類があります。
なぜこのような指定が必要なのかというと、例えば Int
クラスはNumber
クラスのサブクラスとなりますが、変更可能なlistを考えたときに、もしMutableList<Int>
がMutableList<Number>
のサブクラスであるならば、Float
もまたNumber
のサブクラスであるために、Int
で作成したリストに対してFloat
の値が追加できてしまいます。
// Intのリストとして作成 val nums:MutableList<Number> = mutableListOf<Int>(1, 2, 3) // Floatの値が追加できてしまう nums.add(10.5)
invariant(不変)
invariant(不変)とは、クラスB
がクラスA
のサブタイプであるときに、Foo<B>
はFoo<A>
のサブタイプでもなく、スーパータイプでもない、という状態のことです。共変は宣言時になにもつけずに以下のように定義します。
class Invariant<T>(val value:T)
このとき、 Invariant<Number>
型の変数にInvariant<Int>
型のインスタンスを代入しようとするとコンパイルエラーとなります。同様にInvariant<Int>
型の変数にInvariant<Number>
型の変数を代入することもできません。
val num:Invariant<Number> = Invariant<Int>(100) val int:Invariant<Int> = Invariant<Number>(100)
covariant(共変)
covariant(共変)とは、クラスB
がクラスA
のサブタイプであるときに、Foo<B>
はFoo<A>
のサブタイプとなることが出来る、という状態のことで、以下のようにout
修飾子をつかって定義します。
class Covariant<out T>(val value:T)
このとき、 Covariant<Number>
型の変数にCovariant<Int>
型のインスタンスを代入することが出来ますが、Covariant<Int>
型の変数にCovariant<Number>
型の変数を代入しようとするとコンパイルエラーとなります。
val num:Covariant<Number> = Covariant<Int>(100)
val int:Covariant<Int> = Covariant<Number>(100)
このとき、out
という修飾子のついた型パラメータは使用できる箇所が以下に限定されます。
- コンストラクタ
val
で宣言されたプロパティ- メソッドの戻り値
class Covariant<out T>(t: T){ val value1 = t // OK! var value2 = t //コンパイルエラー fun get(): T = value1 fun set(t:T){value2 = 1} // コンパイルエラー }
このとき、get()
の戻り値は、型パラメータで使用された型のスーパータイプで受けることが出来ます。
val num1: Number = 100 val num2: Number = Covariant<Int>(100).get()
メソッドの戻り値として、クラスの外側で受け取る値のみ型パラメータを使用できるという意味で、out
という修飾子になっているのですね。
contravariant(反変)
contravariant(反変)とは、クラスB
がクラスA
のサブタイプであるときに、Foo<A>
がFoo<B>
のサブタイプとなることができる状態のことで、型パラメータを定義しているクラスと型パラメータで指定されるクラスのサブタイプの関係が逆になります。以下のようにin
修飾子を使って定義します。
class Contravariant<in T>(value: T)
contravariant(反変)では、サブタイプの関係は逆転するため、Contravariant<Int>
型の変数にContravariant<Number>
型の変数を代入することは出来ますが、その逆はエラーとなります。
val int:Contravariant<Int> = Contravariant<Number>(10.0)
val num:Contravariant<Number> = Contravariant<Int>(100)
このとき、in
という修飾子のついた型パラメータが使用できる箇所は
- コンストラクタ
- メソッドの引数
のみです。メソッドの戻り値やpublicな変数に型パラメータを使用することは出来ません。
class Contravariant<in T>(t: T){ val value1 = 1 // コンパイルエラー var value2 = 2 // コンパイルエラー fun get(): T = value1 // コンパイルエラー fun set(t: T) {} // OK! }
これらの型パラメータはpublicな変数には使用することは出来ませんが、privateな変数であれば使用することが出来ます。
class Contravariant<in T>(t: T){ private val value1 = 1 // OK! private var value2 = 2 // OK! fun set(t: T) {} // OK! }
このとき、set( )
の引数には型パラメータで使用された型のサブタイプを使用することが出来ます。
val num = Contravariant<Number>(100) num.set(1234567L) num.set(10.0) num.set(123)
メソッドの引数として、クラスで受け取る値を型パラメータで使用できるという意味で、in
という修飾子が使われています。
余談: Nothing型のインスタンス
あと、余談としてNothing
型のインスタンスを生成する方法が紹介されていたのが面白かったです。
How to Test Server-side Kotlin
発表者はエムスリー株式会社の前原秀徳さんと鈴木健太さん。 サーバサイドのKotlinのテストの方法について話をされていました。 自分はサーバサイドでのKotlinの経験がなかったので、どんな感じだろうと思って参加しました。
内容
- 1部: Server-Side Kotlin testing libraries
- サーバサイドKotlin開発時の有用なテストライブラリを紹介
- Kotlinで使う際のTipsやハマりポイントも紹介
- 2部: How do we test Server-Side Kotlin
- 実際のプロジェクトでどのようにテストを書いていたかを紹介
- 3部: Our test tools for Kotlin
- テストのために発表者が作ったツールを紹介
勉強になった点
テスティングライブラリ
サーバサイド開発での有用なテスティングライブラリということでしたが、AssertJ
やMockK
などは、Android開発でのテストでも使用できそうで、使ってみようと思いました。
Factlin
前原さんが自作されたというデータベーススキーマからDb-Setup用のコードを作成できるFactlinというツールを紹介されていました。
DBスキーマからKotlinのテストフィクスチャを自動生成するgradleプラグインを作った - maeharinの日記
Kotlin Fill Class
鈴木さんが開発された、Koltinでクラスのコンストラクタのコードを生成してくれるプラグイン。 プロパティが大量にあるクラスのコードを書くときに便利そうです。 Kotlinでコンストラクタをシュッと書くためにIntellijのプラグインを作った - suusan2号の戯れ
kotlin linter
発表者はDMM.comの釘宮愼之介さん。 Kotlin用のLinterの紹介と、カスタムルールの作成方法について紹介されていました。
内容
- Linterとは
- Ktlint
- インスール方法
- 使い方
- 標準で使用されているルール
- ルールの設定方法
- カスタムルールの作り方
- 作ったカスタムルールの適用方法
- その他
- detekt
- android-lint
- まとめ
発表内容としてはLinterについてのインストール方法と使い方、カスタムルールの作成方法を、Ktlint, detekt, android-lintについてかなり詳細に説明をされていました。
勉強になった点
Psi Viewer
Linterのカスタムルールの作る際には、KotlinのAST(抽象構文木)を辿ってプログラムの構造を解析する必要があります。 このASTに対して、プログラム言語独自の意味付けなどを行ったものをPSI(Program Structure Interface)といいます。IntelliJやAndroid Studio向けには、この構造を可視化するためのプラグインが提供されています。 それが PsiViewerです。
カスタムlint作成時の使用例
このPsiViewerはこのあとの磯貝さんの発表でも紹介されており、lintのカスタムルールだけでなくプラグイン開発など、言語機能の開発者には常識となっているプラグインといえます。
How to Kontribute (v4 JP)
発表者はUbieの磯貝佳典さん。 去年サンフランシスコでおこなわれたKotlin confでも登壇され、とても好評だったと聞いていたので楽しみにしていました。
内容
- Setup development environment
- Communicating with other developers
- First Recommended Kontribution
- Developing/Testing plugin features
勉強になった点
First Recommended Kontribution
KotlinのプロジェクトにKontributeする最も簡単な方法は、公式APIのSampleコードを書くことだそうです。 ステップとしては 1. kotlin-stdlib - Kotlin Programming Languageから使用されていないAPIを探す 2. https://youtrack.jetbrains.net/issue/KT-20357 のissueにて宣言 3. サンプルコードを書いてPRをだす
サンプルコードの記述方法としては@Sample
アノテーションをつけてメソッドなどの記述例を書き、もとのAPIのKDocにその参照先を追加するとのこと。このあたりのやり方もhttps://youtrack.jetbrains.net/issue/KT-20357 から他の人のPRをだどれるのでわかりやすそうです。
感想
日本でこれだけ大きなKotlinのカンファレンスは初めてでしたが、運営もスムーズで、Kotlinへの愛に溢れたとてもよいカンファレンスでした。またサーバサイドでKotlinを使っている企業やプロジェクトが予想以上に多かったのが印象的でした。AndroidだけでなくサーバサイドでもKotlinが広く使われていく可能性を感じました。