Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Kotlinにおける型の世界と エラーハンドリング / Type World and Error Handling in Kotlin

Kotlinにおける型の世界と エラーハンドリング / Type World and Error Handling in Kotlin

mako_makok

March 07, 2023
Tweet

More Decks by mako_makok

Other Decks in Programming

Transcript

  1. 1
    ©2023 Loglass Inc.
    Kotlinにおける型の世界と
    エラーハンドリング
    2023.3.07 Makoto Kobayashi

    View Slide

  2. 2
    2
    ©2023 Loglass Inc.
    小林 允(Makoto Kobayashi)
    自己紹介
    @mako_makok
    mako-makok
    所属: 株式会社ログラス
    好きな言語: Java, Kotlin, TypeScript
    普段はSpringBootをKotlinで書いています
    AndroidをJavaで書いてた
    Luceneのパッチを書いてSolrに組み込む
    JavaでSpringBootやSeasar2を書いていた
    ログラスでSpringBootとKotlinを書いている
    2017〜2018
    2018〜2019
    2019〜2021
    2022〜

    View Slide

  3. 3
    ©2023 Loglass Inc.
    ログラスについて
    Loglassは経営データを正確かつ迅速に可視化/分析す
    ることで、柔軟/高精度な事業推進を実現する経営管理
    クラウドサービス です。
    企業価値を向上する経営管理クラウド

    View Slide

  4. 4
    ©2023 Loglass Inc.
    ログラスについて

    View Slide

  5. 5
    5
    ©2023 Loglass Inc.
    目次
    1. Javaにおけるエラーハンドリング
    2. Kotlinにおける例外処理
    3. Kotlinでのエラーハンドリング
    4. よりメンテナブルなエラーハンドリングに

    View Slide

  6. 6
    ©2023 Loglass Inc.
    Javaにおけるエラーハンドリング

    View Slide

  7. 7
    ©2023 Loglass Inc. 7
    例外のtry-catch
    Javaにおけるエラーハンドリング

    View Slide

  8. 8
    ©2023 Loglass Inc.
    Kotlinの例外処理

    View Slide

  9. 9
    ©2023 Loglass Inc.
    Kotlinにおける例外
    Kotlinの例外処理
    Javaの検査例外をthrowしてもコンパイルエラーにならない

    View Slide

  10. 10
    ©2023 Loglass Inc.
    Kotlinにおける例外
    Kotlinの例外処理
    try-catch式 runCatching

    View Slide

  11. 11
    ©2023 Loglass Inc.
    Kotlinにおける例外
    Kotlinの例外処理
    ● 検査例外がないので例外を無視してもコンパイルエラーにならない
    ● throwsも無いので例外のチェックを強制するような設計は
    絶対できないようになっている
    ● 呼び出し階層の中で例外を投げる処理を書くと
    ハンドリング忘れで意図しないエラーが発生する可能性がある

    View Slide

  12. 12
    ©2023 Loglass Inc.
    Kotlinにおける例外
    Kotlinの例外処理
    設計レベルでなんとかできないかな?
    ● 設計標準に例外ハンドリングについて定義する?
    ● ArchUnitでアーキテクチャテストを書く?

    View Slide

  13. 13
    ©2023 Loglass Inc.
    Kotlinでのエラーハンドリング

    View Slide

  14. 14
    ©2023 Loglass Inc.
    例外のtry-catchに代わるハンドリング
    Kotlinでのエラーハンドリング
    ● 代数的データ構造で Result型を設計する
    ● パターンマッチでokとerrorをハンドルして値を安全に取り出す

    View Slide

  15. 15
    ©2023 Loglass Inc.
    代数的データ構造とは
    Kotlinでのエラーハンドリング
    代数的データ型(だいすうてきデータがた、英 : algebraic data type)とは
    プログラミング、特に関数型プログラミングや型システムにおいて使われ
    るデータ型である。それぞれの代数的データ型の値には、 1個以上のコ
    ンストラクタがあり、各コンストラクタには 0個以上の引数がある。 代数的
    データ型の値(データ)の感覚的な説明としては、引数で与えられた他の
    データ型の値を、コンストラクタで包んだようなもの、である。コンストラク
    タに引数がある代数データ型は複合型(他のデータ型を組み合わせて形
    成する型)である。
    Wikipediaより引用: https://ja.wikipedia.org/wiki/代数的データ型

    View Slide

  16. 16
    ©2023 Loglass Inc.
    代数的データ構造とは
    Kotlinでのエラーハンドリング
    ● パラメータの組み合わせが和や積など、
    代数的に表現できるためそう呼ばれている ?
    ● 厳密的な定義はなさそう ?

    View Slide

  17. 17
    ©2023 Loglass Inc.
    直積型
    Kotlinでのエラーハンドリング

    View Slide

  18. 18
    ©2023 Loglass Inc.
    直積型
    Kotlinでのエラーハンドリング
    data error
    String null
    null String
    null null
    String String
    2 * 2の直積でパターンが表される

    View Slide

  19. 19
    ©2023 Loglass Inc.
    直和型
    Kotlinでのエラーハンドリング
    Resultの型はOkかErrorなので、直和のパターン数で表される

    View Slide

  20. 20
    ©2023 Loglass Inc.
    直和型
    Kotlinでのエラーハンドリング

    View Slide

  21. 21
    ©2023 Loglass Inc.
    余談: こういうのも直和
    Kotlinでのエラーハンドリング

    View Slide

  22. 22
    ©2023 Loglass Inc.
    余談: こういうのも直和
    Kotlinでのエラーハンドリング

    View Slide

  23. 23
    ©2023 Loglass Inc.
    直和型によるエラーハンドリング
    Kotlinでのエラーハンドリング
    ::doSomethingはinterfaceを返却する

    View Slide

  24. 24
    ©2023 Loglass Inc.
    直和型によるエラーハンドリング
    Kotlinでのエラーハンドリング
    パターンマッチによるデータの取り出し

    View Slide

  25. 25
    ©2023 Loglass Inc.
    直和型によるエラーハンドリング
    Kotlinでのエラーハンドリング
    パターンの欠損はコンパイルエラーになる

    View Slide

  26. 26
    ©2023 Loglass Inc.
    Javaでの直和型の実装
    Kotlinでのエラーハンドリング
    instanceof によるパターンマッチ

    View Slide

  27. 27
    ©2023 Loglass Inc.
    Javaでの直和型の実装
    Kotlinでのエラーハンドリング
    Java 19 third preview(Record Patterns, pattern matching for switch)

    View Slide

  28. 28
    ©2023 Loglass Inc.
    よりメンテナブルな
    エラーハンドリングに

    View Slide

  29. 29
    ©2023 Loglass Inc.
    言語機能の限界
    よりメンテナブルなエラーハンドリングに

    View Slide

  30. 30
    ©2023 Loglass Inc.
    言語機能の限界
    よりメンテナブルなエラーハンドリングに
    Resultがネストするとかなり可読性が下がる

    View Slide

  31. 31
    ©2023 Loglass Inc.
    言語機能の限界
    よりメンテナブルなエラーハンドリングに
    ● 直和型とパターンマッチは特に関数型言語にしばしば見られる概念である
    ● Kotlinは関数型ではない
    ● もう一歩関数型に踏み込む必要がある

    View Slide

  32. 32
    ©2023 Loglass Inc.
    他の言語のパラダイムを確認する : Rust
    よりメンテナブルなエラーハンドリングに

    View Slide

  33. 33
    ©2023 Loglass Inc.
    他の言語のパラダイムを確認する : Scala
    よりメンテナブルなエラーハンドリングに

    View Slide

  34. 34
    ©2023 Loglass Inc.
    and_thenの実装
    よりメンテナブルなエラーハンドリングに
    ● 関数の合成はシンタックス的に難しそう
    ● Rustではand_then, ScalaではflatMapがある
    ● どちらも同じ動きをしている
    ● これらを模倣してみると良さそう

    View Slide

  35. 35
    ©2023 Loglass Inc.
    and_thenの実装(1/3)
    よりメンテナブルなエラーハンドリングに
    ● out: Kotlinにおける共変を表す
    ● Nothing: 存在しない値を表す型

    View Slide

  36. 36
    ©2023 Loglass Inc.
    and_thenの実装(2/3)
    よりメンテナブルなエラーハンドリングに
    ● 拡張関数: fun Result.funName() {} と宣言することで、
    クラスにメソッドが生えているかのような書き方ができる
    ● 引数部分は関数渡し
    図の場合、引数は Function>と同等

    View Slide

  37. 37
    ©2023 Loglass Inc.
    and_thenの実装(3/3)
    よりメンテナブルなエラーハンドリングに

    View Slide

  38. 38
    38
    ©2023 Loglass Inc.
    Nothing型
    よりメンテナブルなエラーハンドリングに
    ● Any型の反対
    ● 全てのクラスを継承したクラス
    ● Nothingはインスタンスを生成することができない
    ● ex) 必ず例外を送出するようなメソッド
    ● ex) 型引数が省略できないとき Nothingを指定する

    View Slide

  39. 39
    39
    ©2023 Loglass Inc.
    必ず例外を送出するメソッド
    よりメンテナブルなエラーハンドリングに
    ● fail() とかも適していそう
    ● ロギング + 例外送出
    ● etc…

    View Slide

  40. 40
    ©2023 Loglass Inc.
    型引数が省略できないとき
    よりメンテナブルなエラーハンドリングに
    ● Resultの型引数はTとEを取る
    ● OkはTだけでいいし、ErrorはEだけでいい
    ● しかし型引数は省略できないので Nothingを使う

    View Slide

  41. 41
    ©2023 Loglass Inc.
    kotlin-resultの紹介
    よりメンテナブルなエラーハンドリングに
    ● サンプルコードをいくつかご紹介しました
    ● kotlin-resultというライブラリを利用すると、
    これまでのことが一瞬でできるようになります
    ○ https://github.com/michaelbull/kotlin-result
    implementation("com.michael-bull.kotlin-result:kotlin-result:1.1.16" )

    View Slide

  42. 42
    ©2023 Loglass Inc.
    kotlin-resultの紹介
    よりメンテナブルなエラーハンドリングに
    kotlin-resultのGitHubページより引用

    View Slide

  43. 43
    ©2023 Loglass Inc.
    kotlin-resultの紹介
    よりメンテナブルなエラーハンドリングに

    View Slide

  44. 44
    ©2023 Loglass Inc.
    まとめ

    View Slide

  45. 45
    ©2023 Loglass Inc.
    今回のサマリ
    まとめ
    1. Kotlinに検査例外は無い
    2. エラーハンドリングをする際は直和型 + パターンマッチで
    Result型を設計すべし
    3. kotlin-resultを導入すると、Result型をすぐに使い始められる

    View Slide

  46. 46
    46
    ©2023 Loglass Inc.
    参考文献
    まとめ
    ● 代数的データ型
    ○ https://ja.wikipedia.org/wiki/代数的データ型
    ● kotlin-result
    ○ https://github.com/michaelbull/kotlin-result
    ● KotlinでResult型使うならkotlin-resultを使おう
    ○ https://note.com/yasukotelin/n/n6d9e352c344c
    ● Rust By Example
    ○ https://doc.rust-jp.rs/rust-by-example-ja/error/opti
    on_unwrap/and_then.html
    ● Scala の Option, Either とエラー処理
    ○ https://engineering.mobalab.net/2020/09/24/scala
    -error-handling-option-either

    View Slide

  47. 47

    View Slide