Kotlin enum과 when
enum
enum은 열거형(enumerated type)이라고 부른다. 열거형은 서로 연관된 상수들의 집합이라고 할 수 있다.
enum은 아래와 같이 사용합니다.
enum class Color{
RED,ORANGE,YELLOW,GREEN,BLUE,INDIGO
}
위는 기본적인 형태이고, 흔히 자바에서 사용할땐
enum값 내부에 멤버 변수를 설정하기도 합니다.
enum class Color{
RED(255,0,0),ORANGE(255,165,0),YELLOW(255,255,0),GREEN(0,255,0),BLUE(0,0,255),INDIGO(75,0,130)
fun rgb()=(r*256+g) *256+b
}
fun main(args:Array){
println(Color.BLUE.rgb())
}
enum 내부에 값과 함수까지 정의했습니다.
코틀린에서는 ;를 사용하지 않지만 enum의 마지막에는 반드시 사용해야 합니다.
when에 enum을 사용
fun getMnemoic(color:Color)=when(color){
Color.RED->"Richard"
Color.ORANGE->"Of"
Color.YELLOW->"York"
Color.GREEN->"Gave"
Color.BLUE->"Battle"
Color.INDIGO->"In"
}
fun main(agrs:Array){
println(getMnemonic(Color.BLUE))
}
when의 특징은 break를 넣지않아도 된다는 점입니다.
만약 여러값으로 분기하고자 한다면 "," 콤마를 사용하면 됩니다.
when의 인자로 Object 사용하기
when은 object를 인자로 받을 수 있기 때문에 아래와 같은 사용도 가능합니다
fun getMnemoic(color:Color)=when(color){
Color.RED,Color.ORANGE->"Richard"
Color.YELLOW->"York"
}
fun mix(c1:Color,c2:Color)=when(setOf(c1,c2)){
setOf(RED,YELLOW)->ORANGE
setOf(YELLOW,BLUE)->GREEN
else->throw Exception("Dirty color")
}
fun main(args:Array){
println(mix(BLUE,YELLOW))
}
setOf는 java로 이야기하면 set을 만드는 함수입니다.
c1과 c2에 들어오는 순서는 상관없이
mix(REX,YELLOW)와 mix(YELLOW,RED)는 둘다 상관없이 ORANGE가 반환됩니다.
또한 else를 이용하여 남은 처리를 할 수도 있습니다.
인자없는 when
fun mixOptimized(c1:Color,c2:Color)=
when{
(c1 ==RED && c2 ==YELLOW) ||
(c1 ==YELLOW && c2 ==RED)->
ORANGE
....
else ->throw Exception("Dirty color")
}
fun main (args:Array){
println(mixOptimized(BLUE,YELLOW))
}
인자값 없이 when을 사용하는경우에는 조건부분은 반드시 Boolean을 반환하는 expression 이여야 합니다.
스마트 캐스트
코틀린의 장점중 하나는 스마트캐스트를 지원한다는 점입니다.
스마트 캐스트란 obejct의 타입 확인과 변환을 한번에 해주는 기능입니다.
interface Expr //아무함수도 없는 Dummy interface를 만든다
class Num(val value:Int):Expr
class Sum(val left:Expr, val right:Expr):Expr
fun eval(e:Expr):Int{
if(e is Num){ //smart Cast가 발생한다
val n= e as Num //e를 Num Type으로 전환하지만 , 이미 smart cast 되어 Num 타입입니다(생략가능)
return n.value
}
if (e is Sum){ //smart Cast가 발생한다
//이미 e는 Sum type으로 변환된 상태이므로 as를 이용하여 변환할 필요가 없다
return eval(e.right) + eval(e.left) //sum의 property에 바로 접근 가능
}
throw IllegalArgumentException("Unkown expression")
}
fun main(args:Array){
prinln(eval(Sum(Sum(Num(1),Num(2),Num(4))))
}
위 예제를 보면 Num과 Sum은 모두 Expr 이라는 interface를 구현하고 있습니다.
is 는 instanceof와 같은 역할이라고 보면 되며 as는 강제 캐스팅이라고 보면 됩니다.
if를 써도 되지만 when을 쓰면 더 간결합니다.
fun eval(e:Expr):Int=
when(e){
is Num->
e.value
is Sum->
eval(e.right)+eval(e.left)
else->
throw IllegalArgumentException("Unknown expression")
}
}
댓글