美文网首页
kotlin基础知识二: enum和when

kotlin基础知识二: enum和when

作者: 北雁南飞_8854 | 来源:发表于2020-05-03 14:18 被阅读0次

一、enum class

1. 声明一个带有属性的enum class

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
}

在kotlin语法中唯一需要使用分号的地方:
在enum class中使用分号将enum constant list和method definitions分隔开。

2. 使用"when"来处理enum class

when在kotlin中是一个表达式(expression),用于checking values for equality。
因此,可以使用when写一个expression body类型的函数。

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

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

3. when表达式的参数可以是任意类型的对象

fun mix(c1: Color, c2: Color) =
    when (setOf(c1, c2)) {
        setOf(Color.RED, Color.YELLOW) -> Color.ORANGE
        setOf(Color.YELLOW, Color.BLUE) -> Color.GREEN
        setOf(Color.BLUE, Color.VIOLET) -> Color.INDIGO
        else -> throw Exception("Dirty color")
    }

4. when表达式也可以不带参数

fun mixOptimized(c1: Color, c2: Color) =
    when {
        (c1 == Color.RED && c2 == Color.YELLOW) ||
                (c1 == Color.YELLOW && c2 == Color.RED) ->
            Color.ORANGE
        (c1 == Color.YELLOW && c2 == Color.BLUE) ||
                (c1 == Color.BLUE && c2 == Color.YELLOW) ->
            Color.GREEN
        (c1 == Color.BLUE && c2 == Color.VIOLET) ||
                (c1 == Color.VIOLET && c2 == Color.BLUE) ->
            Color.INDIGO
        else -> throw Exception("Dirty color")
    }

二、smart cast

使用is关键字校验类型之后,不需要再做显式的类型转换,编译器会帮忙做这个转换。

package com.example.kotlin
import java.lang.IllegalArgumentException

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
        return n.value
    }

    if (e is Sum) {
        return eval(e.left) + eval(e.right)
    }

    throw IllegalArgumentException("Unknown expression")
}

注:Kotlin中没有三目运算符。与Java不同的是,Kotlin的if表达式会返回一个value。因此可以使用expression-body语法重写上面的eval()方法。

fun eval(e: Expr): Int =
    if (e is Num) {
        e.value
    } else if (e is Sum) {
        eval(e.left) + eval(e.right)
    } else {
        throw IllegalArgumentException("Unknown expression")
    }

如果if branch中只有一个expression,则花括号可以省掉。
如果if branch是block body,则最后一个expression的值会作为结果返回。

1. 使用when替换if

这里的"when"branches是用来check the argument type。

fun eval(e: Expr): Int =
    when (e) {
        is Num -> e.value
        is Sum -> eval(e.left) + eval(e.right)
        else -> throw IllegalArgumentException("Unknown expression")
    }

注意:"the last expression in a block is the result"

fun evalWithLogging(e: Expr): Int =
    when (e) {
        is Num -> {
            println("num: ${e.value}")
            //block中的最后一个表达式的值, 被当做结果返回.
            e.value
        }

        is Sum -> {
            val left = evalWithLogging(e.left)
            val right = evalWithLogging(e.right)
            println("sum: $left + $right")
            //block中的最后一个表达式的值, 被当做结果返回.
            left + right
        }

        else -> throw IllegalArgumentException("Unknown expression")
    }

相关文章

网友评论

      本文标题:kotlin基础知识二: enum和when

      本文链接:https://www.haomeiwen.com/subject/uhnlghtx.html