패턴 부합

패턴 부합(pattern matching) 기능으로 다양한 경우에 따른 식을 평가하기 좋습니다.

def daysToString(day: Int): String = day match {
  case 1 => "하루"
  case 2 => "이틀"
  case 3 => "사흘"
  case 4 => "나흘"
  case _ => day + "일"
}

daysToString(2) // => "이틀"
daysToString(5) // => "5일"

match 블록 안에서 case 키워드로 시작하는 다양한 경우를 나열하며 => 기호로 평가할 식을 적습니다. 자바의 switch 구문과 달리, 해당 식만 평가하고 결괏값이 나오기 때문에 별도로 break 키워드는 쓰지 않습니다.

여기서 _ 기호는 모든 경우를 다 아우르는 용도로 쓰는 관례입니다. default로 이해해도 좋습니다.

케이스 클래스와 패턴 부합

케이스 클래스를 패턴 부합과 함께 쓰면 편리합니다.

trait Animal
case class Cat(name: String, kind: String) extends Animal
case class Dog(name: String, age: Int) extends Animal
case class Person(name: String, adult: Boolean) extends Animal

Animal 트레이트를 확장한 케이스 클래스를 준비했습니다. 다시 말해, Cat, Dog, Person 셋 다 Animal입니다.

def show(animal: Animal): String =
  animal match {
    case Cat(name, kind) => s"고양이 ${name}은 ${kind}종입니다."
    case Dog(name, age) => s"강아지 ${name}는 ${age}살입니다."
    case Person(name, true) => s"${name}님은 성인입니다."
    case Person(name, false) => s"${name}님은 미성년자입니다."
  }

show(Dog("금비", 3))        // => "강아지 금비는 3살입니다."
show(Person("홍길동", true)) // => 홍길동님은 성인입니다.

Animal을 파라미터로 받아서 패턴 부합으로 분류해서, 문자열로 변환했습니다. case로 분류하면서, 멤버 변수의 값을 바로 접근해서 쓸 수 있다는 점이 특별합니다.

평가식에서, dog.name이나 dog.age를 따로 접근할 필요 없이, 곧바로 nameage를 추출했습니다.

그리고, 추출할 대상값에 상수를, 그러니까 위 예제에서는 truefalse를, 두고 패턴 부합 분류에 쓰기도 합니다.