2.2エラーの基礎/選択表示と処理:enumとwhen


コトリンのwhenはjavaのswitchに取って代わったが、より強く、よりよく使われている.

2.3.1 enumクラスの定義

enum class Color{
    RED,ORANGE,YELLOW,GREEN,BLUE,
}
Enumは、単純な値のみをリストするのではなく、Propertyまたはメソッドを定義できます.
enum class Color(
        val r: Int, val g: Int, val b: Int
) {
    RED(255, 0, 0), ORANGE(255, 165, 0),
    YELLOW(255, 255, 0), GREEN(0, 255, 0), BLUE(0, 0, 255),
    INDIGO(75, 0, 130), VIOLET(238, 130, 238);

    fun rgb() = (r * 256 + g) * 256 + b
}

fun main(args: Array<String>) {
    println(Color.BLUE.rgb())
}
これはコトリンの唯一のものです.使用が見られます.
Enumクラスでメザードラーを定義します.
enum定数リストとメソッド定義の間にセミコロンを追加する必要があります.

2.3.2 whenを使用してenumクラスを処理する

enum class Color {
    RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET
}

fun getMnemonic(color: Color) =
    when (color) {
        Color.RED -> "Richard"
        Color.ORANGE -> "Of"
        Color.YELLOW -> "York"
        Color.GREEN -> "Gave"
        Color.BLUE -> "Battle"
        Color.INDIGO -> "In"
        Color.VIOLET -> "Vain"
    }

fun main(args: Array<String>) {
    println(getMnemonic(Color.BLUE))
}
Javaとは異なり、breakを置く必要はありません.
1四半期に複数の値を組み合わせモードとして使用できます.この場合、利用できます.
enum class Color {
    RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET
}

fun getWarmth(color: Color) = when(color) {
    Color.RED, Color.ORANGE, Color.YELLOW -> "warm"
    Color.GREEN -> "neutral"
    Color.BLUE, Color.INDIGO, Color.VIOLET -> "cold"
}

fun main(args: Array<String>) {
    p

2.3.3 whenを任意のオブジェクトと一緒に使用する


定数しか使用できないJava switchとは異なり、コトリンのwhenはすべてのオブジェクトを許可します.
fun mix(c1: Color, c2: Color) =
        when (setOf(c1, c2)) {
            setOf(RED, YELLOW) -> ORANGE
            setOf(YELLOW, BLUE) -> GREEN
            setOf(BLUE, VIOLET) -> INDIGO
            else -> throw Exception("Dirty color")
        }

fun main(args: Array<String>) {
    println(mix(BLUE, YELLOW))
}

2.3.4使用時パラメータなし


パラメータがない場合、コードの読み取りは困難になりますが、パフォーマンスはさらに向上します.
fun mixOptimized(c1: Color, c2: Color) =
    when {
        (c1 == RED && c2 == YELLOW) ||
        (c1 == YELLOW && c2 == RED) ->
            ORANGE

        (c1 == YELLOW && c2 == BLUE) ||
        (c1 == BLUE && c2 == YELLOW) ->
            GREEN

        (c1 == BLUE && c2 == VIOLET) ||
        (c1 == VIOLET && c2 == BLUE) ->
            INDIGO

        else -> throw Exception("Dirty color")
    }

fun main(args: Array<String>) {
    println(mixOptimized(BLUE, YELLOW))
}
上のコードはwhenにパラメータがありません
=>Boolean値.

2.3.5インテリジェント鋳造:タイプ検査とタイプ鋳造を組み合わせて

interface Expr
class Num(val value: Int) : Expr
class Sum(val left: Expr, val right: Expr) : Expr

fun eval(e: Expr): Int {
    if (e is Num) {
        val n = e as Num       //1)
        return n.value
    }
    if (e is Sum) {
        return eval(e.right) + eval(e.left) //2)
    }
    throw IllegalArgumentException("Unknown expression")
}

fun main(args: Array<String>) {
    println(eval(Sum(Sum(Num(1), Num(2)), Num(4))))
}

sumの場合、左右のパラメータを左右のプロパティとして格納します.
Exprインタフェースには2つの実装クラスが含まれています
したがって,式を評価するには,二つのケースを考慮する必要がある.
  • 任意の式数であれば、その値
  • を返す.
  • ある形式の合計であれば、左と右の値を計算し、2つの値の和の値を返します.
  • 1)タイプをNumからNumに変換することは不要である.
    2)変数eに対してインテリジェント鋳造を用いる.
  • コトリンでは、isを使用して変数タイプをチェックします.
  • で所望のタイプで明示的にタイプを選択したい場合は、それを培養物として使用する.
  • インテリジェント鋳造は、値が変更できない場合にのみ機能します!=>このpropertyへのアクセスが常に同じ値を与えていることを確認する必要があります.

    2.3.6再包装:ifをいつに変更するか

    fun eval(e: Expr): Int =
        if (e is Num) {
            e.value
        } else if (e is Sum) {
            eval(e.right) + eval(e.left)
        } else {
            throw IllegalArgumentException("Unknown expression")
        }
    
    fun main(args: Array<String>) {
        println(eval(Sum(Num(1), Num(2))))
    }
    上のコードをwhenで裁断しましょう.
    fun eval(e: Expr): Int =
        when (e) {
            is Num -> //1)
                e.value  //2)
            is Sum -> //1)
                eval(e.right) + eval(e.left)  //2)
            else ->
                throw IllegalArgumentException("Unknown expression")
        }
    
    fun main(args: Array<String>) {
        println(eval(Sum(Num(1), Num(2))))
    }
    1)パラメータタイプチェック時のブランチ
    2)この部分ではスマートブロードキャストを使用している.
    タイプをチェックすると、スマート放送が行われます
    ->NumまたはSumのメンバーにアクセスする場合は、強制的に変数を選択する必要はありません.

    2.3.7 ifブランチとwhenブランチでのブロックの使用

    fun evalWithLogging(e: Expr): Int =
        when (e) {
            is Num -> {
                println("num: ${e.value}")
                e.value    //1)
            }
            is Sum -> {
                val left = evalWithLogging(e.left)
                val right = evalWithLogging(e.right)
                println("sum: $left + $right")
                left + right   //2)
            }
            else -> throw IllegalArgumentException("Unknown expression")
        }
    
    fun main(args: Array<String>) {
        println(evalWithLogging(Sum(Sum(Num(1), Num(2)), Num(4))))
    }
    
    1)eのタイプがNumの場合、ブロックの最後の式であるため、e.valueが返されます.
    2)eのタイプがsumの場合、式の値が返されます.