IMCAT.DEV
로그인 가입
Scala 입문 자료구조

Scala 옵셔널 (Option) 타입

Scala 옵셔널 (Option) 타입 — 초급

옵셔널 (Option) 타입

1. 도입 (왜 배워야 하는가)

Scala에서 Option 타입은 데이터를 다룰 때 매우 중요한 역할을 합니다. 실제 프로그래밍에서는 null 값으로 인해 발생하는 오류가 빈번히 발생합니다. 예를 들어, 어떤 객체가 null일 때 이를 처리하지 않으면 NullPointerException이 발생하여 프로그램이 중단될 수 있습니다.

Option 타입은 이러한 문제를 해결하기 위해 설계되었습니다. Option은 값이 존재할 수도 있고 존재하지 않을 수도 있음을 명시적으로 나타내므로, 코드의 안전성을 높이고 오류를 줄일 수 있습니다.

따라서 Option 타입을 이해하지 못하면 코드에서 null 체크를 소홀히 하게 되어, 예기치 않은 오류를 초래할 수 있습니다.

2. 핵심 개념 설명

Option 타입

Option은 두 가지 상태를 가질 수 있습니다:
  • Some(value): 값이 존재하는 경우
  • None: 값이 존재하지 않는 경우
  • 이 개념은 실생활의 상자에 비유할 수 있습니다. 상자 안에 물건이 있을 수도 있고, 비어 있을 수도 있습니다. 상자가 비어 있을 때는 물건을 찾을 수 없듯이, None을 만났을 때는 값을 찾을 수 없음을 의미합니다.

    용어설명
    Some값이 존재함을 나타냄
    None값이 존재하지 않음을 나타냄
    OptionSome 또는 None의 조합을 나타냄

    3. 기본 코드 예제

    아래는 Option 타입의 기본 사용법을 보여주는 코드입니다.

    val someValue: Option[Int] = Some(10)  // Some 타입으로 값 10을 감싸기
    val noneValue: Option[Int] = None       // 값이 없는 경우 None
    
    // Option 타입의 값 사용
    someValue match {
      case Some(value) => println(s"값이 존재합니다: $value")
      case None => println("값이 존재하지 않습니다.")
    }
    
    // noneValue를 사용해 보겠습니다.
    noneValue match {
      case Some(value) => println(s"값이 존재합니다: $value")
      case None => println("값이 존재하지 않습니다.")
    }

    실행 결과

    값이 존재합니다: 10
    값이 존재하지 않습니다.

    코드 한 줄씩 동작 설명

    1. val someValue: Option[Int] = Some(10) - 값 10을 Some으로 감싸 Option 타입의 someValue를 생성합니다.
    2. val noneValue: Option[Int] = None - 값이 없는 경우를 표현하기 위해 None을 사용하여 noneValue를 생성합니다.
    3. match 문을 사용하여 someValue의 값을 검사합니다.
    4. Some(value)에 해당하면 해당 값을 출력하고, None이면 값이 없다는 메시지를 출력합니다.
    5. 다시 noneValue를 검사하여 결과를 출력합니다.
    6. 4. 실전 활용 예제

      예제 1: 사용자 정보 검색

      쇼핑몰에서 사용자의 정보를 데이터베이스에서 조회할 때, 사용자가 존재하지 않을 경우를 고려해야 합니다.

      def findUser(userId: Int): Option[String] = {
        // 데이터베이스에서 사용자 검색 (가상의 데이터베이스)
        val users = Map(1 -> "김철수", 2 -> "이영희")
        users.get(userId) // userId가 존재하면 Some(name), 없으면 None 반환
      }
      
      val user = findUser(1) // Some("김철수")
      user match {
        case Some(name) => println(s"사용자 이름: $name")
        case None => println("사용자를 찾을 수 없습니다.")
      }

      예제 2: 선택적 장바구니 아이템 추가

      쇼핑몰에서 장바구니에 아이템을 추가할 때, 이미 존재하는 경우와 없는 경우를 처리합니다.

      def addItemToCart(cart: List[String], item: String): Option[List[String]] = {
        if (cart.contains(item)) None else Some(item :: cart)
      }
      
      val cart = List("사과", "바나나")
      val updatedCart = addItemToCart(cart, "사과") // None 반환
      updatedCart match {
        case Some(newCart) => println(s"장바구니 업데이트: $newCart")
        case None => println("이미 장바구니에 존재하는 아이템입니다.")
      }

      5. 흔한 실수와 주의사항

      실수 1: Option을 사용하지 않고 null 체크

      // 잘못된 코드
      val value: String = null
      if (value != null) {
        println(value)
      }

      위 코드는 null 체크를 통해 오류를 방지하려하지만, Option을 사용하지 않아 여전히 안전하지 않습니다.

      실수 2: Option의 값을 직접적으로 사용

      // 잘못된 코드
      val someValue: Option[Int] = Some(10)
      println(someValue.get) // get 메소드를 사용하면 안전하지 않음
      get 메소드는 None일 경우 NoSuchElementException을 발생시킬 수 있으므로, 매칭을 통해 안전하게 처리하는 것이 좋습니다.

      6. 정리

    7. Option 타입은 값의 존재 여부를 명시적으로 표현할 수 있는 타입입니다.
    8. Some과 None을 사용하여 null로 인한 오류를 방지할 수 있습니다.
    9. 실무에서는 데이터베이스 조회, API 호출 등에서 자주 사용됩니다.
    10. Option을 사용할 때는 get 메소드를 피하고 패턴 매칭을 사용하는 것이 안전합니다.

다음에 학습하면 좋은 주제: Scala의 고차 함수와 컬렉션 처리.