10
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

KotlinでのSwiftのEnum Associated Values相当のことをする方法

Last updated at Posted at 2017-11-16

SwiftのEnumには便利な機能があって、enumを利用するときにenumの要素に付属する値を設定することができます。
代数的データ型(Algebraic data type)というそうです。

例えば、Httpエラーコードのenumを定義して、statusCodeやその時のresponseをmapで設定したい場合は以下のように書けます。

HttpErrorType.swift
public enum HttpErrorType: Error {

    case timedOutError 
    case cannotFindHost
    case cannotConnectToHost 
    case statusCode(Int, [AnyHashable: Any]?)
}

判定するときは、以下のように書けます

            switch errorType {
            case .timedOutError:
                print("タイムアウト")
            case .cannotFindHost, .cannotConnectToHost:
                print("サーバー接続できない")
            case let .statusCode(401, detail):
                print("ログインして")
            case .statusCode(500, _):
                print("サーバーエラー")
        }

そして網羅チェックもしてくれます。
例えば、timedOutErrorをswitch文に入れてなければ、add missing case: '.timedOutError'とコンパイラが知らせてくれます。

Kotlinのenumでは同じことができませんが、sealedを使えば同じようなことができます。
Kotlinの sealed はクラスの継承を制限するための修飾子です。
sealed クラスはサブクラスを持つことができますが、それらのすべて同じファイルで宣言されなければなりません。 詳しくはコメント欄を確認してください。
( C#のsealedはJavaのfinalと同等なのでC#の人は注意です。)

HttpErrorType.kt
sealed class HttpErrorType

object TimedOutError : HttpErrorType()
object CannotFindHost : HttpErrorType()
object CannotConnectToHost : HttpErrorType()
data class StatusCode(val code: Int, val map: Map<String, Any>?) : HttpErrorType()    

判定方法は、以下になります。

        when (errorType) {
            is TimedOutError -> print("タイムアウト")
            is CannotFindHost, is CannotConnectToHost -> print("サーバー接続できない")
            is StatusCode -> {
                when (type.code) {
                    400 -> print("ログインして")
                    500 -> print("サーバーエラー")
                    else -> print("その他")
                }
            }
        }.let { }

Kotlinでは、残念ながらパターンマッチができないのでStatusCodeの中身を分解して判断する必要があります。(その際にelseも必要になります)
最後の.let{} は、コンパイラに網羅チェックをしてもらうために書いています。

10
7
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?