2.3 enum, when, is, as - ericbykim/kotlin-in-action GitHub Wiki

enum

  • enum์€ soft keyword์ด๋‹ค. class์•ž์— ์žˆ์„ ๋•Œ๋Š” ํŠน๋ณ„ํ•œ ์˜๋ฏธ๋ฅผ ์ง€๋‹ˆ์ง€๋งŒ ๋‹ค๋ฅธ ๊ณณ์—์„œ๋Š” ์ด๋ฆ„์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
enum class Color (
	val r: Int, val g: Int, val b: Int
) {
	RED(255,0,0), ORANGE(255,165,0),YELLO(255,255,0), ...
	VIOLET(238,130,238); // <- ๋ฐ˜๋“œ์‹œ ์„ธ๋ฏธ์ฝœ๋ก ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

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

when

  • ์ž๋ฐ”์˜ switch ๋ฌธ์— ํ•ด๋‹นํ•˜๋Š” ์ฝ”ํ‹€๋ฆฐ ์š”์†Œ
fun getMnmonic(color: Color) = 
	when (color) {
		Color.RED -> "Richard"
		Color.ORANGE -> "Of"
		Color.YELLOW -> "York"
		...
		Color.VIOLET -> "Vain"
	}
  • ์—ฌ๋Ÿฌ ๊ฐœ ๋งค์นญ
fun getWarmth(color: Color) = when(color) {
	Color.RED, Color.ORANGE, Color.YELLOW -> "Warm"
	Color.BLUE, Color.INDIGO, Color.VIOLET -> "Cold"
	else -> "i don't know"
}
  • ์œ„ ์ฝ”๋“œ๋ฅผ ๋” ๊ฐ„๋‹จํ•˜๊ฒŒ?
fun getWarmth(color: Color) = when(color) {
	RED, ORANGE, YELLOW -> "Warm"
	BLUE, INDIGO, VIOLET -> "Cold"
	else -> "i don't know"
}
  • ํ˜ผํ•ฉ ์กฐ๊ฑด์œผ๋กœ ๋งค์นญ
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")
	}

println(mix(BLUE, YELLOW)) // GREEN
  • ์œ„์ฒ˜๋Ÿผ setOf๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด set์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•ด์„œ ๊ฐ€๋น„์ง€ ๊ฐ์ฒด๊ฐ€ ๋Š˜์–ด๋‚œ๋‹ค. ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ ๋ณด๋‹ค ์„ฑ๋Šฅ์ด ๋” ์ค‘์š”ํ•  ๋•Œ๋„ ์žˆ๋‹ค.
// ๊ฐ€๋…์„ฑ์€ ๋–จ์–ด์ง€์ง€๋งŒ ์ถ”๊ฐ€ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์ง€ ์•Š๋Š” ์žฅ์ ์ด ์žˆ๋‹ค.
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")
	}
  • Kotlin 1.3 ๋ถ€ํ„ฐ ๊ฐ€๋Šฅ: When์˜ ๋Œ€์ƒ์„ ๋ณ€์ˆ˜์— ๋Œ€์ž…
fun Request.getBody() =
	when(val response = executeRequest()) {
		is Success -> response.body
		is HttpError -> throw HttpException(response.status)
	}

Smart Cast: ํƒ€์ž… ๊ฒ€์‚ฌ + ํƒ€์ž… ์บ์ŠคํŠธ๋ฅผ ์กฐํ•ฉ (is, as)

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

// println ( eval(Sum(Sum(Num(1), Num(2)), Num(4))) )
// -> 7
  • ์ž๋ฐ” ์Šคํƒ€์ผ ๊ตฌํ˜„ (if ์‚ฌ์šฉ)
fun eval(e: Expr) : Int {
	if (e is Num) {
		val n = e as Num // ๋ถˆํ•„์š”ํ•œ ์ฝ”๋“œ (์Šค๋งˆํŠธ ์บ์ŠคํŠธ๋กœ ์ด๋ฏธ Num์œผ๋กœ ์บ์ŠคํŠธ ๋จ)
		return n.value
	}
	if (e is Sum) {
		return eval(e.right) + eval(e.left) // ์Šค๋งˆํŠธ ์บ์ŠคํŠธ ๋จ
	}
	throw IllegalArgumentException("Unknown expression")
}
  • ์Šค๋งˆํŠธ ์บ์ŠคํŠธ: is ๋ฅผ ํ†ตํ•ด ํƒ€์ž… ์ฒดํฌ๋ฅผ ํ•˜๋ฉด ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์›ํ•˜๋Š” ํƒ€์ž…์œผ๋กœ ์บ์ŠคํŠธ ํ•ด์ค€๋‹ค.
  • is ๋Š” ์ž๋ฐ”์˜ instanceof ์™€ ๋น„์Šทํ•˜๋‹ค.
  • ์Šค๋งˆํŠธ ์บ์ŠคํŠธ ์•ˆํ•˜๋Š” ๊ฒฝ์šฐ: val์ด ์•„๋‹ˆ๊ฑฐ๋‚˜ val์ด์ง€๋งŒ ์ปค์Šคํ…€ ์ ‘๊ทผ์ž๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” ํ•ด๋‹น ํ”„๋กœํผํ‹ฐ์— ๋Œ€ํ•œ ์ ‘๊ทผ์ด ํ•ญ์ƒ ๊ฐ™์€ ๊ฐ’์„ ๋‚ด๋†“๋Š”๋‹ค๊ณ  ํ™•์‹ ํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์Šค๋งˆํŠธ ์บ์ŠคํŠธ ํ•˜์ง€ ์•Š๋Š”๋‹ค.
  • ๋ช…์‹œ์  ํƒ€์ž… ์บ์ŠคํŒ… as
  • ์ฝ”ํ‹€๋ฆฐ ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„
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 eval(e: Expr) : Int = 
	when (e) {
		is Num -> e.value // ์Šค๋งˆํŠธ ์บ์ŠคํŠธ ๋จ
		is Sum -> eval(e.right) + eval(e.left) // ์Šค๋งˆํŠธ ์บ์ŠคํŠธ ๋จ
		else -> throw IllegalArgumentException("Unknown expression")
	}
  • ๋ธ”๋ก ์‚ฌ์šฉ
fun eval(e: Expr) : Int = 
	when (e) {
		is Num -> {
			println("num: ${e.value}")
			e.value
		}

		is Sum -> {
			val left = eval(e.left)
			val right = eval(e.right)
			println("sum: $left + $right")
			left + right
		}

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