Sansan Tech Blog

Sansanのものづくりを支えるメンバーの技術やデザイン、プロダクトマネジメントの情報を発信

Kotlin Fest 2018に行ってきた

Eight事業部でEightのAndroid版の開発を担当している山本です。

2018年8月25日に行われた。Kotlin Fest 2018に行ってきました。

Sansan株式会社ではKotlin勉強会を2016年から行っており、私自身もKotlin入門までの助走読本の執筆に参加したり、Kotlin in Actionの翻訳に参加するなど、Kotlinとは深く関係してきたので、今回のイベントはとても楽しみにしていました。

f:id:boohbah:20180906175653j:plain

また、Sansanは今回のKotlin Festにはスポンサーとして参加しました。スポンサーブースには、たくさんの方々にお越しいただきました。ありがとうございました。

セッションの資料の一覧はこちら

この中で自分が参加したセッションについてレポートしていきたいと思います。

オープニングセッション

オープニングセッションでは日本Kotlinユーザーグループ会長のたろうさんによる、これまでのKotlinの歩みの振り返りとKotlinのコミュニティ活動についての説明がありました。また、同じく日本Kotlinユーザーグループの藤原聖さんは、Kotlinの特徴や哲学、Kotlinを知るためのリソースについて紹介されていました。

そして、今回のテーマは「Kotlinを愛でる」です。 これは、自分も翻訳に参加させていただいた「Kotlin イン アクション」の第2部のタイトルで、原著では「Embracing Kotlin」となっており、翻訳時にこれをどう訳すのかについて熱く議論したことを思い出しました。

f:id:boohbah:20180906174553j:plain

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という修飾子が使われています。

Kotlinもう一歩 - Speaker Deck

余談: 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
    • テストのために発表者が作ったツールを紹介

勉強になった点

テスティングライブラリ

サーバサイド開発での有用なテスティングライブラリということでしたが、AssertJMockKなどは、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)

photos.google.com

発表者は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が広く使われていく可能性を感じました。

© Sansan, Inc.