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

Kotlin serializationの使い方を詳しく調べてみた

Kotlin serializationの使い方を詳しく調べてみた

Wataru Mizukami

January 21, 2019
Tweet

More Decks by Wataru Mizukami

Other Decks in Programming

Transcript

  1. Kotlin serializationの使い方を詳しく
    調べてみた
    Wataru Mizukami(水上 亘)

    View Slide

  2. 自己紹介
    Wataru Mizukami/水上 亘
    Twitter/Github/Qiita: @tarumzu (たる)
    Organization/所属: sikmi, inc.

    View Slide

  3. Kotlin serializationとは
    - シリアライザ・デシリアライザである(コード自動生成用のコンパイラプラグインとシリ
    アライズ用のランタイムライブラリの構成)
    - JSON, CBOR, Protobufの3つのフォーマットをサポートし、
    さらに有志が作成したアドオンを使えばHOCON, YAMLも使える
    https://github.com/Kotlin/kotlinx.serialization/blob/master/formats/README.md
    - Kotlin/JVM, Kotlin/JS, Kotlin/Nativeプラットフォームをサポート
    - リフレクションを使用しない

    View Slide

  4. Kotlin serializationとは
    - シリアライザ・デシリアライザである(コード自動生成用のコンパイラプラグインとシリ
    アライズ用のランタイムライブラリの構成)
    - JSON, CBOR, Protobufの3つのフォーマットをサポートし、
    さらに有志が作成したアドオン使えばHOCON, YAMLも使える
    https://github.com/Kotlin/kotlinx.serialization/blob/master/formats/README.md
    - Kotlin/JVM, Kotlin/JS, Kotlin/Nativeプラットフォームをサポート
    - リフレクションを使用しない 
    ー> リフレクション使用しない分速い!

    View Slide

  5. build.gradle
    Androidでの設定方法について記述する。その他のプラットフォーム用の設定は公式参照のこと
    buildscript {
    ext.kotlin_version = '1.3.11'
    repositories { jcenter() }
    dependencies {
    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
    }
    }

    View Slide

  6. app/build.gradle
    apply plugin: 'kotlin'
    apply plugin: 'kotlinx-serialization'
    // 略
    repositories {
    jcenter()
    // artifacts are published to this repository
    maven { url "https://kotlin.bintray.com/kotlinx" }
    }
    dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:0.9.1"
    }

    View Slide

  7. 使い方
    import kotlinx.serialization.*
    import kotlinx.serialization.json.JSON
    @Serializable
    data class Data(val a: Int, @Optional val b: String = "42")
    fun main(args: Array) {
    // Serializableアノテーションを付けた場合、オブジェクトを渡すだけ
    val jsonData = JSON.stringify(Data(42))
    // コレクション等も拡張関数
    serializerを使うことで利用可能
    val jsonList = JSON.stringify(Data.serializer().list, listOf(Data(42)))
    println(jsonData) // {"a": 42, "b": "42"}
    println(jsonList) // [{"a": 42, "b": "42"}]
    // 文字列をパースするときも簡単!
    val obj = JSON.parse("""{"a":42}""")
    println(obj) // Data(a=42, b="42")
    }
    引用元: https://github.com/Kotlin/kotlinx.serialization#quick-example

    View Slide

  8. 使い方2
    @Serializable
    class Data(val a: Int) {
    private val b: String = "42"
    override fun equals(other: Any?) = /*...*/
    }
    // unquotedはフォーマットからダブルクォーテーションを外す
    assertEquals("{a:1, b:42}", JSON.unquoted.stringify(Data(1)))
    assertEquals(Data(1), JSON.unquoted.parse("{a:1, b:42}"))
    引用元: https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/examples.md#supported-properties

    View Slide

  9. アノテーションについて
    - Serializable : シリアライズしたいカスタムクラスに付けることでシリアライゼーションできる
    - Optional : 必須ではないパラメータの場合はオプショナルをつけないとエラーになる
    - SerialName : JSONキー名が異なる場合に付ける
    -
    - Transient : JSONで扱わないプロパティを定義したい場合に使用する。
     JSONにこのプロパティが存在していた場合エラーになる
    - SerialInfo : アノテーションクラスを定義するためのアノテーション。
    プロパティにタグなどの情報をもたせることが出来て、
    エンコーダー内でタグをもとに条件分岐などに利用できる。
    Protobufなどで利用する

    View Slide

  10. アノテーションの使い方
    // シリアライズしたいクラスに付与
    @Serializable
    data class Data(
    val a: Int,
    // 必須パラメーターではない場合に付ける
    @Optional
    val b: String = “42”,
    // jsonキー名がcでプロパティ名とことなる場合
    @SerialName("c")
    val d: String
    )
    - SerialInfoの例は下記参照
    https://github.com/Kotlin/kotlinx.serialization/blob/bb6e21e2c05cf6fa7d9a1b7f0c401d0afe726eda/runtime/com
    mon/src/test/kotlin/kotlinx/serialization/protobuf/SampleClasses.kt

    View Slide

  11. カスタムシリアライザ
    シリアライザを自作することも可能。このサンプルは日付を扱う例
    @Serializer(forClass = Date::class)
    object DateSerializer: KSerializer {
    private val df: DateFormat = SimpleDateFormat("dd/MM/yyyy HH:mm:ss.SSS")
    override val descriptor: SerialDescriptor =
    StringDescriptor.withName("WithCustomDefault")
    override fun serialize(output: Encoder, obj: Date) {
    output.encode(df.format(obj))
    }
    override fun deserialize(input: Decoder): Date {
    return df.parse(input.decode())
    }
    }
    引用元:
    https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/custom_serializers.md#external-serializers-for-library-classes

    View Slide

  12. ご清聴、ありがとうございました!

    View Slide