一、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")
}
网友评论