Kotlin Fest 2018 に参加した話
皆さんはじめまして @mzkii です.普段は Kotlin を使って Android アプリ開発をしたり,Python を使って データ分析をしたりしています.
この記事では,8/25(土)に開催された Kotlin Fest 2018 に スカラシップ枠 として参加しましたので,その様子をレポートしていきたいと思います.
目次
- 参加するまでの経緯
- 参加する目的
- セッション
- LT大会
- ブースと懇談会
- おわりに
参加するまでの経緯
このカンファレンスは,DroidKaigi 2018 のオープニングセッションにてサプライズ告知され,自分自身とても楽しみにしていたのですが,ついに7月の頭に開催決定のツイートが流れてきました!!
Kotlin Fest 2018 開催のお知らせ #kotlinfest - 算譜王におれはなる!!!! https://t.co/Pm0JmjLHsN
— Kotlin Fest 2018 (@kotlin_fest) 2018年7月3日
Kotlin Fest 2018 のイベントページを公開しました!スピーカーのみなさまのご紹介を掲載しております。お申込みは7/24正午に開始します #kotlinfest #jkughttps://t.co/CU7kJJt0qC
— Kotlin Fest 2018 (@kotlin_fest) 2018年7月18日
さらに,8月に入って サイバーエージェント さんが「Kotlin Fest 2018」スカラシップ枠を募集していると Twitter で知り,(既にチケット買っちゃってましたが) ダメ元で応募してみると... 見事参加できることになりました!
【Developers Blog更新✏️✨】
— 【公式】サイバーエージェント新卒技術採用 (@ca_tec_des) 2018年8月2日
サイバーエージェントにて「Kotlin Fest 2018」スカラシップ枠の募集を開始https://t.co/140Sf56Uco #サイバーエージェント #ブログ #CAエントリー
Kotlin Fest 2018 における スカラシップ枠 とは,
・Kotlin Fest 2018 のチケット提供(懇親会 有) ・希望者には8月24日(金)の社内見学・技術者とのランチ会に参加いただけます。 ・遠方在住の方には宿泊場所を手配。 ・交通費支給。
※ 公式ページ より抜粋
となっており,地方学生にとってはとっても嬉しいプランでした😉
また,申し込みには,
・Kotlin Conferenceに参加したい理由を300文字以内で ・githubアカウント ・これでの制作物で一番よく出来たもののURLなど
※ 公式ページ より抜粋
以上3項目を書いて送るだけ!とっても簡単でした!
参加する目的
このカンファレンスは,「Kotlinを愛でる」をビジョンに,Kotlin の知識の共有や,Kotlin を愛してやまない人々に対して交流の場を提供することを目的に開催されました.僕自身,普段から Kotlin は使っていますし,第一線で活躍されているエンジニアの方々と交流を深めながら Kotlin の言語仕様を理解することはもちろん,Android x Kotlin に関する最新技術をキャッチアップしたい!と思って参加しました(特に Kotlin Coroutine).
セッション
早速セッションについてみていきましょう.本当は全部のセッション見たかったのですが,2セッション同時に発表されるので,タイトル見て直感で,面白そう x 明日からすぐに役立ちそう
なセッションをピックアップしてみました.
Kotlin で改善する Android アプリの品質
概要
なぜ品質の話?
Android アプリにおける品質とは?
- 速い
- 落ちない
- 使いやすい
- 変更しやすい
- 読みやすい
ソフトウェアの品質 = 要因の組み合わせ
- 内的品質要因 ... スピード,使いやすさなど
- 外的品質要因 ... モジュール性,読みやすさなど
- 特に重要な要因は...
- 正確さ + 頑丈さ = まとめて信頼性と呼ぶ
- 拡張性 + 再利用性 = まとめてモジュール性と呼ぶ
- 特に重要な要因は...
Java で広く実践されている規則は Kotlin だとどうなる??
Kotlin アプリのリファクタリングポイント
概要
- Gradle Kotlin DSL
- Gradle のスクリプトを Kotlin で書ける(build.gradle.kts)
- 補完・ジャンプコードが効くぞい
- 処理の共通化
- Mutable を避ける
- 今どんな値が入っているのか常に考えないといけなくなる
- 暗黙の前提はバグの温床
- その var は本当に var にしないといけないのか? (ここの話に使われていた遷移図がめっちゃ分かりやすかった)
- その MutableList は本当に MutableList にしないといけないのか?
- var と MutableList の併用は避ける
- val x MutableList の組み合わせ
- var x List の組み合わせ
- var と MutableList の併用は避ける
- 今どんな値が入っているのか常に考えないといけなくなる
Collection
- List と MutableList,実体はどっちも ArrayList
- List は 読み取り専用であり,Immutable ではない
- Collection の生成は,基本的には listOf,setOf,mapOf
- 他にも,パフォーマンスを考慮して,setOf,linkedSetOf,hashSetOf,sortedSetOf があるので使うとよいぞ
- Collection のリファクタリング
- 2つのリストを同時に使う --> zip
- 変換と除外 --> map,filter,mapNotNull
- リストを N 個ずつに分割 --> withIndex でインデックスを付けて,さらに groupBy でグループ分け
- できるだけ否定「!」は使わない --> all,any,none の活用
DSL の拡張
- Domain Specific Language
- 内部DSL とも呼ばれ,Kotlin の言語機能で実現可能
- 構造的なデータ宣言,設定値の記述が簡潔になる
- Anko や Spek などに使われてる機能らしいが僕にはまだ早かった...
- Nullability
- Kotlin といえば Nullability が嬉しい
- しかし API が Nullable を返した場合,UI 層までのどの層まで Nullable として扱うか問題が出てくる
- return team?.user?.name?.length
- null が何を表しているか明確にしよう
- 滅多に起きないエラーケース --> infra で Exception に変換
- 任意項目でかつ存在していないを表していることが自明 --> UI 層まで Nullable で渡す
- 自明じゃない何か --> sealed class を作ってその状態に意味付けする
- スコープ関数
- キャプチャする時
- null 判定時の値が使えるので smart cast が効かないときに有効
- 単に if 文の代わりにもなる
- ただし if 文と全く同じなわけではない
- 処理をまとめたい時
- Intent の putExtra など
- ただしローカル変数名との衝突に注意
- Intent の putExtra など
- キャプチャする時
- データ構造と状態数
- 肥大しがちな data class
- バグの温床なので,ビジネスロジックを考慮して,ありえない状態を避けよう
- 状態整理 --> Either,Pair
- 意味付け --> sealed class,data class
- 状態数を数式に落とし込むと,より厳密に精査できる👀
- バグの温床なので,ビジネスロジックを考慮して,ありえない状態を避けよう
- 肥大しがちな data class
start from Convert to Kotlin
- RecyclerView を使ったサンプルアプリを Java --> Kotlin にしながら言語仕様をみてみる
@Parcelize data class KotlinItem(var id Int = 0, var name String? = null) : Parcelable { fun isSameItem(obj Any): Boolean { return ((obj as? KotlinItem)?.id == this.id) } }
KotlinItem(var id Int = 0, var name String? = null)
- data class で toString などのメソッドを生やす
- equals
- hashCode
- toString
- copy
data class KotlinItem ...
@Parcelize data class KotlinItem ...
- 安全キャスト
- Any を KotlinItem に変換できるか?
- キャストできなかったら null を返す
- Any を KotlinItem に変換できるか?
obj as? KotlinItem
Kotlin コルーチンを理解しよう
- コルーチンとはなにか
- Kotlin ではコルーチンをどうやって実現しているのか
- コルーチンをステートマシンに変換している
- 中断と再開を状態遷移と考える
- もちろん再開に必要な情報もステートマシンに持っておく
- 逐次内部状態を変えながら実行
- コルーチン --> ステートマシン
- ここで出てくるのが
suspend修飾子
ラムダ式
につけるとコルーチン本体関数
につけると中断する場所を表す
- コルーチンを任意のタイミングで再開するには??
- 実は,suspend 関数にはコンパイル時に継続インターフェースの引数が生える
- 継続インターフェースを使って再開処理
- suspend ラムダはコルーチンの範囲を決める
- ここで出てくるのが
- 正直コルーチンを自作するのはしんどい
- そこで出てくるのがコルーチンビルダー
- launch(結果を伴わないコルーチンビルダー),async(結果を返すコルーチンビルダー) ...
- 継続インターセプターで実行スレッドを指定できる
- CommonPool,JavaFx,UI,Swing
- そこで出てくるのがコルーチンビルダー
- コルーチンをステートマシンに変換している
- Kotlin コルーチンの基本的な使い方
- まずは launch(結果を伴わないコルーチン)を作成してみる
- start ... コルーチンの開始方法
- parent ... 複数のコルーチンを一気にキャンセルしたい場合などに親Jobを指定する
- onCompletion ... コルーチン終了時に呼び出されるコールバック関数を指定
- context ... 共有データや継続インターセプター
- 例えば Android で UI をいじるコルーチンを作る場合は,デフォルトではスレッドプールでコルーチンが走ってしまうので,launch(UI) でコルーチンの処理は常にUIスレッド上で再開するように継続インターセプターを指定する.
- async / await
- エラーハンドリング
- 普通に try-catch を使う
- コルーチンの直列・並列実行
- 擬似コードで表すと,
- まずは launch(結果を伴わないコルーチン)を作成してみる
直列実行 val token = async { getToken() } ... ここは中断しない val profile = async { loadProfile(token.await()) }.await() ... token で結果を待ってから loadProfile を実行する 並列実行 val token = async { getToken() } ... 中断しない val profile = async { loadProfile() } ... 中断しない show(token.await(), profile.await()) ... 一気に await して結果待ち
- キャンセル
- リトライ
- コルーチン内で,repeat(3) などしておいて,処理が正常終了した場合は return@launch でコルーチンを終了し,なにか Exception が発生した場合に,リトライしなくなかったら return@repeat 等でリトライ処理を抜けるようにする.
- (読めば理解できるけど,個人的に冗長で読みにくい気がしなくもない...)
- コルーチンの応用例
- retrofit ... 結果を Deferred< T > で受け取れる Jake作の Adapter がある
- EventBus x Cnannel
- onActivityResult ... android-coroutines を使えば,activity を起動して結果を受け取るまでを一つのコルーチン内で簡潔に書ける
LT大会
LT大会では,8名の方々が発表してくださいました.
一人あたり3分だったので,スピード感ある発表でどれも面白かったです😉
ここでは,スライドが公開されていて,特に印象に残っていた発表を紹介します.
3分で分かる Sequence
- List では コレクション操作のたびに毎回新しい List を作成する(先行評価)
- Sequence では 終端操作(toList など)を走らせるまでは処理が実行されない(遅延評価)
- 要素数と操作数が少ない --> List, 多い --> Sequence で使い分けよう
RxJavaを使っている 既存アプリに Kotlin Coroutinesを導入しよう
Single<List<Person>>
をsuspend List<Person>
に変換してみる- ただし,実際のところ Single なメソッドを複数箇所から呼び出していることが多いので,一つだけ置き換えはできない
- そんなあなたに
kotlinx-coroutines-rx2
があるよ - Single に await メソッドが生えるので,中断関数に変換できる
- しかしプロダクションコードでは,テスト,ライフサイクル,エラーハンドリングも必要になってくる
- この辺りの話は @takahirom さんのこの記事が参考になる
J2K コンバータをカスタマイズする
純正J2Kコンバータが強制的にNonNull変換する問題
Convert Java File to Kotlin File
を使うと Nullable なコードが NonNull コードに変換されてしまう- 親Class,Interface,abstractクラスなどメソッドを継承した場合
- 引数に
@Nullable
がない場合 - Kotlin は NonNull で Java は Nullable 環境になってしまう
- Illegalstateexception や Nullpointerexception の原因に
解決策
カスタムコンバータを導入してみて
- hotfix 切ることが激減した
- コードの信頼感が高まりレビューが簡素化
- 何より手軽に Java --> Kotlin ができるようになった😉
ブースと懇談会
最後に,展示ブースと懇談会の様子をお届けします.
ブースで面白かったのが,サイバーエージェントさんの Kotlin Puzzlers です.
午前午後と2問ずつ Kotlin に関する問題が出題されていたのですが,
これがめちゃ難問でした(それぞれ1問ずつしか解けなかった😂).
本日はKotlin Fest 2018です。サイバーエージェントのブースでは、Kotlin Puzzlersを実施中!ぜひ遊びに来てください〜! pic.twitter.com/iJu3kSGw8Y
— CyberAgentDevelopers (@ca_developers) 2018年8月25日
また,ヤフーさんのブースでは黒帯本がもらえる抽選会や,
モブプログラミング教室も開催されており,かなり盛り上がっていました!
写真は黒帯抽選会の様子です
そしてなんと抽選会当たりました笑(ありがとうございます)
#KotlinFest Yahoo さんのブースにて頂きました!ありがとうございます😊 pic.twitter.com/7KkNwEp6ru
— はんちょー (@fmzk326) 2018年8月25日
クロージング後はブースやっていた場所で懇談会をやることになりました.
とりあえず写真貼っていきます(肉が美味しかった).
おわりに
Kotlin Fest 2018 の様子をレポートしてみましたがいかがでしたか? さらに詳しく知りたい方は,#kotlinfest で ツイッター検索してみると,ここでは紹介しきれなかったセッション資料や,ブース展示の様子などよく分かりますよ!
次回開催はまだ未定とのことですが,今回のイベントは大盛況でしたし,是非来年も開催してほしいです(今度はLT枠などで喋ってみたい).今後も Android x Kotlin のイベントには積極的に参加していくので,僕もイベントを盛り上げられる一員となれるように楽しくやっていきたいと思います!
最後に,Kotlin Fest を開催してくださった運営の皆様,スポンサーの皆様,さらにスカラシップ枠を用意してくださったサイバーエージェント様ありがとうございました.こういったスカラシッププログラムは,地方学生にとっては非常にありがたい内容ですし,今後も継続していただけると,全国の学生の助けになると思います.
ここまでお読み頂きありがとうございました🙇
Kotlin かわいい!
おしまい