dev-signer
개자이너
dev-signer
전체 방문자
오늘
어제
  • 분류 전체보기 (20)
    • Project (8)
      • DIMODAMO (1)
      • Menual (6)
      • WatchOS (1)
    • iOS (9)
      • Swift (6)
      • UI (2)
    • 코딩테스트 (2)
    • 일상 (1)
      • 이야기 (1)

블로그 메뉴

  • 홈
  • 태그

공지사항

인기 글

태그

  • 파이썬
  • 주니어개발자
  • 사이드프로젝트
  • 파이썬 알고리즘 인터뷰
  • tuist
  • XCode
  • 리뷰요청하기
  • 알고리즘
  • Swift
  • SnapKit
  • 스위프트
  • swfit
  • 코딩테스트
  • 메뉴얼
  • 디지털미디어디자인
  • watchos
  • Dependency Injection
  • 의존성주입
  • ios
  • menual

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
dev-signer

개자이너

[Swift] Enum
iOS/Swift

[Swift] Enum

2022. 12. 26. 14:28

Struct를 활용해서 채팅 메세지를 만든다고 가정해보겠습니다.
채팅메세지에는 아래와 같은 형식을 가지고 있습니다.

  1. 일반적인 텍스트 메세지
  2. 채팅 참가 메세지
  3. 채팅 탈퇴 메세지

위와 같은 메세지 형태를 Struct로 표현했을 경우와 Enum으로 표현했을 경우에는 어떤 차이점이 있는지 확인해보겠습니다.

1. Struct

struct Message {
    let userId: Int
    let contents: String?
    let data: Date
    
    let hasJoined: Bool
    let hasLeft: Bool
}

let joinMessage = Message(userId: 1, contents: nil, date: Date(), hasJoined: true, hasLeft: false)
let textMessage = Message(userId: 1, contents: "Hello World", date: Date(), hasJoined: false, hasLeft: false))
let leftMessage = Message(userId: 1, contents: nil, date: Date(), hasJoined: true, hasLeft: true))

Struct를 활용하면 잘못된 상태의 객체가 만들어질 수 있습니다.

let wrongMessage = Message(userId: 1, contents: "Hi", hasJoined: true, hasLeft: true)

이처럼 의도하지 않은 잘못된 상태의 객체가 만들어질 수 없도록 효율적인 방법이 없을까요?

2. Enum

  1. Enum은 '상호 배타적'인 관계를 표현할 수 있습니다.
  2. 연관 값(Tuple)을 이용하면, 데이터도 포함할 수 있습니다.
enum Message {
    case text(userId: Int, contents: String, date: Date)
    case join(userId: Int, date: Date)
    case leave(userId: Int, date: Date)
}

let joinMessage: Message = Message.join(userId: 1, contents: "hello", date: Date())

let textMessage = Message.text(userId: 1, contents: "hello", date: Date())

let leaveMessage: Message = .leave(userId: 1, date: Date())

enum을 활용한 switch-case문을 활용할 경우에는 default와 같이 모든 case에 대해서 처리하는 것 보다는, 모든 경우를 처리하는 형태로 만들어 놓는 것이 좋습니다.

func logMessage(message: Message) {
    switch message {
    	case .text(userId: let userId, contents: let contents, date: let date):
        break

        case .join(userId: let userId, date: let date):
        break

        case .leave(userId: let userId, date: let date):
        break
    }
}

default로 모든 경우를 처리할 경우에 enum에 새로운 값이 추가되었을 경우에 컴파일러가 오류 없이 처리하기 때문에, 개발자가 의도치 않은 작동을 막아주는 역할을 기대할 수 없기 때문입니다.

switch-case

Enum을 사용하다 보면 if-else보다는 switch-case를 자주 사용하게 됩니다. 때문에 다양한 표현 방법을 알고 있는 것이 큰 도움이 될 때가 있습니다.

switch message {
    case let .text(userId, contents, date):
    break
    
    case let .join(userId, date):
    break
    
    case let .leave(userId, date):
    break
}

단일 항목 처리

if case .text(userId: let userId, contents: let contents, date: let date) = textMessage {
    ...
}

if case .join(let userId, let contents) = joinMessage {
    ...
}

if case let .leave(userId, date) = leaveMessage {
    ...
}

Type Check

enum DataType {
    case date(Date)
    case string(String)
    case int(Int)
    case double(Double)
    
    // 새로운 항목이 추가되면, 컴파일러가 오류를 통해 처리해야 하는 부분을 알려줍니다.
    case intRange(Range<Int>)
    // 1...10: CloseRange
    // 0..<10: Range
    
    case dateRange(Range<Date>)
}

let startDate = Date()
let endDate = Date().addingTimeInterval(10)

let arr: [DataType] = [
    .date(Date()),
    .string("Hello"),
    .int(42),
    .double(3.14),
    .intRange(1 ..< 10),
    .dateRange(startDate ..< endDate)
]

for element in arr {
    switch element {
    case let .date(date):
	print(date)
    case let .string(string):
	print(string)
    case let .int(int):
    	print(int)
    case let .double(double):
    	print(double)
    case let .intRnage(range):
    	for e in range {
            print(e)
        }
    case let .dateRange(range):
        print(range)
    }
}
반응형

'iOS > Swift' 카테고리의 다른 글

[Swift] 프로퍼티(Property)  (0) 2022.12.26
[Swift] Enum2  (0) 2022.12.26
[Swift] 상속  (0) 2022.12.26
[Swift] Tuple  (0) 2022.12.26
[Swift] 문자열 (String)  (0) 2022.12.26
    'iOS/Swift' 카테고리의 다른 글
    • [Swift] Enum2
    • [Swift] 상속
    • [Swift] Tuple
    • [Swift] 문자열 (String)
    dev-signer
    dev-signer

    티스토리툴바