열거형(Enum) 기본편


swieeft | 2020. 02. 29. 00:20

열거형이란, 연관된 항목을 묶어서 표현할 때 사용 되는 타입을 말합니다. 이미 지정된 항목 값 외에는 추가/수정이 불가능하여 다음의 경우에 많이 사용됩니다.

  • 제한된 선택지를 줄 때
  • 정해진 값 외에는 입력을 받지 않기 위해
  • 예상 된 입력 값이 정해져 있을 때

스위프트의 열거형은 다른 언어의 열거형과는 많은 차이점이 있습니다. C언어를 예를 들면 C언어에서 열거형은 단순히 정수형의 닉네임을 정해 주는 형태로 사용 되었습니다. 그렇기 때문에 모든 열거형의 타입은 정수형으로 취급 되었고, 그렇기 때문에 열거형 각각의 고유 값을 가질 수 없어 실수로 잘못 사용 되어 버그가 발생하는 경우가 많이 있었습니다.

하지만 스위프트 열거형이 고유의 타입으로 존재하기 때문에 위와 같은 상황이 발생할 가능성을 막을 수 있습니다. 그리고 고유의 타입 뿐만 아니라 원시 값(Raw Value)이라는 형태로 정수, 실수, 문자 등의 실제 값을 가질 수 있습니다.

서론이 길어 졌는데요. 그럼 열거형에 대해 하나하나 상세히 알아보도록 하겠습니다.

이해를 빠르게 하기 위해 열거형을 한글로 작성하도록 하겠습니다.

기본 열거형


열거형은 enum이라는 키워드를 이용해 선언할 수 있습니다.

  • 기본 열거형 선언

    우리는 이제 분식집을 차려보려고 합니다. 분식집의 대표적인 메뉴 네가지를 선언한 열거형입니다.

    C언어에서는 위와 같이 선언되면 라면 = 0, 김밥 = 1, 찌개 = 2, 떡볶이 = 3 처럼 정수 값이 설정되지만 스위프트에서는 각각의 case 자체가 하나의 값이 되게 됩니다.

  • 열거형 한 줄 로 선언

    열거형은 쉼표(,)로 구분하여 한 줄로 선언할 수도 있습니다.

열거형 변수 및 패턴 매칭을 통한 열거형 사용법


열거형이 선언되고, 열거형을 사용하기 위한 변수를 만들 수 있습니다.

  • 열거형 변수 생성

  • 열거형 변수 값 변경

  • 열거형 변수 print

    열거형 변수를 print 문을 통해 출력하면 변수 안에 설정 된 값이 출력 됩니다.

    print를 통해 보면 문자열 처럼 보일 수 있지만 분식집.라면이 하나의 고유 값이기 때문에 아래와 같이 문자열로 비교할 수 없습니다.

  • 패턴 매칭을 통한 열거형 사용법

내부(Sub) 열거형


열거형의 서브 타입을 이용하여 좀 더 세분화 된 케이스를 사용하고 싶다면 내부 열거형을 만들어서 사용하면 됩니다.

  • 내부 열거형 선언

    분식집은 여러가지 종류의 메뉴가 있습니다.

    그래서 분식집 메뉴판을 보면 전체 메뉴판 안에 소메뉴를 두어 각각의 타입을 분류 하므로 손님이 메뉴판을 더 쉽게 볼 수 있게 해줍니다.

  • 내부 열거형 변수 생성

    내부 열거형을 사용하여 각 메뉴별로 세분화 된 메뉴를 선택할 수 있는 계층적인 방법이 만들어졌습니다.

  • 클래스, 구조체에 내부 열거형 선언

    열거형 내부에 열거형을 선언할 수 있듯이 클래스, 구조체 내부에도 열거형을 사용할 수 있습니다.

원시 값(Raw Values)


스위프트 열거형의 경우 다른 언어와는 다르게 고유한 자신만의 타입으로 생성 될 뿐만 아니라 원시 값이라는 것을 통해 정수, 실수, 문자 등의 실제 값을 가질 수 있습니다.

  • 원시 값 지정

    원시 값을 지정하는 방법은 간단합니다. 선언 된 열거형 이름 옆에 원시 값으로 사용할 타입을 명시 해준 후 각 항목 마다 사용할 원시 값을 지정 해주면 됩니다.

  • 원시 값 사용

    원시 값을 사용하려면 rawValue라는 프로퍼티를 사용하면 됩니다.

  • 원시 값 자동 처리

    원시 값을 일부 항목에만 적용해도 Int, String은 스위프트가 알아서 자동으로 원시 값을 생성 해줍니다. 단, 실수 타입의 경우 자동 처리를 사용할 수 없습니다.

    • String 타입 원시 값 자동 처리

      String의 경우 원시 값이 지정 된 항목은 지정 된 값을 출력 해주고, 지정 안 된 항목의 경우는 항목 이름 그대로 출력 해줍니다.

    • Int 타입 원시 값 자동 처리

      Int의 경우 원시 값이 지정 된 항목은 지정 된 값을 출력 해주고, 그렇지 않으면 0부터 1씩 값이 늘어납니다.

      라면 값을 100으로 지정 해주면 100에 1씩 증가한 값이 나오게 됩니다.

      중간에 있는 김밥에 값을 100으로 지정 해주면 처음엔 0부터 시작하다가, 김밥 이후부터는 100에서 1씩 증가한 값이 나오게 됩니다.

  • 원시 값을 이용해 열거형 초기화

    원시 값을 알고 있으면 원시 값을 이용해서 열거형을 초기화해 변수를 만들어 줄 수 있습니다. 단, 원시 값이 열거형에 정의 되어 있지 않다면 nil을 반환하게 되므로 생성되는 변수는 옵셔널 변수가 됩니다.

연관 값(Associated Values)


연관 값은 스위프트 열거형의 특징 중 하나로 열거형의 항목들이 각각 자신의 연관 값을 가질 수 습니다. 연관 값은 각 항목 옆에 튜플(Tuple) 형태로 만들 수 있습니다.

연관 값은 모든 항목에 들어갈 필요는 없습니다.

연관 값을 사용하게 되면 원시 값은 사용할 수 없습니다.

  • 연관 값을 가지는 항목 만들기

    연관 값을 이용해 메뉴를 선택 후 원하는 재료를 고르고 몇개를 주문할 지 선택할 수 있게 만들었습니다.

  • 연관 값 사용

    연관 값을 사용할 땐 패턴 매칭을 사용하시면 됩니다.

  • 레이블이 없는 연관 값

    연관 값에 레이블을 생략해서 작성할 수 있습니다. 하지만 이렇게 사용하면 어떤 값이 들어와야 되는지 명확하지 않을 수 있어 사용에 유의해야 합니다.

  • 내부 열거형을 이용한 연관 값 사용

    재료를 손님이 원하는 대로 넣어주기엔 케이스가 많기 때문에 분식집에서 사용할 수 있는 재료로 한정해서 메뉴를 고를 수 있도록 만들어야 합니다.

    • 라면 : 떡, 치즈, 만두
    • 김밥 : 야채, 참치, 김치

열거형 내부 프로퍼티(Property)


열거형에서도 프로퍼티를 사용할 수 있습니다. 하지만 저장 프로퍼티는 사용하지 못하고, 연산 프로퍼티만 사용 가능합니다.

  • 프로퍼티 선언하기

    메뉴라는 연산 프로퍼티를 만들어 주었습니다. 프로퍼티는 모든 항목에서 동일하게 동작하므로 switch문을 이용해 적절히 분기하여 사용해야 합니다.

  • 프로퍼티 사용하기

    메뉴이름 프로퍼티를 사용하여 현재 선택된 재료로 만든 메뉴이름을 받을 수 있습니다.

  • 프로퍼티로 원시 값 만들기

    연관 값을 사용하면 원시 값을 사용하지 못한다고 하였습니다. 하지만 프로퍼티를 이용하면 원시 값 처럼 사용할 수 있게 만들 수 있습니다.

  • 정적 프로퍼티

    열거형에서도 프로퍼티를 정적으로 만들 수 있습니다. 구조체나 클래스에서 정적 프로퍼티를 만들듯이 프로퍼티 앞에 static 키워드를 넣어주면 됩니다.

열거형 내부 메서드(Method)


스위프트 열거형에서는 내부에 메서드도 구현을 할 수 있습니다. 메서드를 구현 해주어 각 항목에 따른 기능을 구현 해줄 수 있습니다.

  • 메서드 선언

    주문한 메뉴의 갯수를 추가 할 수 있게 갯수추가하기라는 메서드를 선언하였습니다. 이 메서드 안에서는 먼저 주문한 메뉴의 갯수과 추가 주문한 갯수를 더한 값을 print합니다.

    메서드도 프로퍼티와 마찬가지로 모든 항목이 동일한 메서드를 사용하기 때문에 switch문을 이용해 적절히 분기하여 사용해야 합니다.

  • 메서드 사용

  • 정적 메서드

    메서드도 클래스, 구조체에서 처럼 정적 메서드를 만들어서 사용할 수 있습니다. 정적 메서드는 메서드 선언할 때 앞에 static 키워드를 추가하면 됩니다.

    정적 메서드를 만들어 메뉴판의 모든 메뉴를 출력하는 함수를 만들었습니다.

    하지만 정적 메서드를 가장 많이 활용하는 것은 위의 코드처럼 단순 print용으로 사용되는 것이 아니라 API로 받아온 값을 열거형으로 바꿀 때 많이 사용 됩니다.

    API에서 메뉴, 재료, 갯수를 내려주면 유효한 메뉴인지 판단하는 함수를 만들어서 사용할 수 있습니다.

  • 변경 메서드

    열거형도 구조체와 마찬가지로 Call by Value이기 때문에 내부 메서드에서 현재 값을 변경하려면 mutating 키워드를 사용해야 self를 변경할 수 있습니다.

마무리


지금까지 열거형 기본편을 알아보았습니다. 기존에 다른 언어에서 알던 열거형과는 다른 하나의 근사한 데이터 타입으로 탄생한 스위프트 열거형입니다.

저도 열거형의 기능을 알고 난 뒤로 많은 부분을 열거형으로 바꿔서 코드를 깔끔하게 짰던 것이 생각이 납니다. 예제는 단편적인 예 밖에 들지 못 했지만 프로젝트를 하다보면 공통적으로 묶여야 되는 부분들도 많고 한데 적절히 열거형을 활용해보면 좋을 것 같습니다.

저 같은 경우에는 API 파라메터에 대한 부분을 열거형으로 만들어 놓고 쓰는데 여러분도 프로젝트에서 어떤 부분을 열거형으로 쓰면 좋을지 생각 해보셨으면 좋겠습니다.

생각보다 긴 글이 되었는데 끝까지 읽어주셔서 감사합니다. 달콤한 개발 되세요!

참고자료