🔥 열거형과 구조체

550자
7분

Swift에서는 enum을 사용하여 열거형을 생성할 수 있어요. 클래스나 다른 이름이 있는 유형과 마찬가지로, 열거형에도 연관된 메서드를 가질 수 있답니다.

enum Rank: Int {
    case ace = 1
    case two, three, four, five, six, seven, eight, nine, ten
    case jack, queen, king
 
    func simpleDescription() -> String {
        switch self {
        case .ace:
            return "ace"
        case .jack:
            return "jack"
        case .queen:
            return "queen"
        case .king:
            return "king"
        default:
            return String(self.rawValue)
        }
    }
}
 
let ace = Rank.ace
let aceRawValue = ace.rawValue
swift

Swift는 기본적으로 원시 값을 0부터 시작하여 1씩 증가시키면서 할당하지만, 값을 명시적으로 지정하여 이 동작을 변경할 수 있어요. 위의 예시에서 Ace는 명시적으로 원시 값 1을 부여받았고, 나머지 원시 값은 순서대로 할당되었습니다. 열거형의 원시 유형으로 문자열이나 부동 소수점 숫자를 사용할 수도 있어요. rawValue 속성을 사용하여 열거형 케이스의 원시 값에 접근할 수 있답니다.

init?(rawValue:) 이니셜라이저를 사용하여 원시 값으로부터 열거형의 인스턴스를 생성할 수 있어요. 이는 원시 값과 일치하는 열거형 케이스를 반환하거나, 일치하는 Rank가 없는 경우 nil을 반환합니다.

if let convertedRank = Rank(rawValue: 3) {
    let threeDescription = convertedRank.simpleDescription()
}
 
swift

열거형의 케이스 값은 실제 값이지, 단순히 원시 값을 다른 방식으로 작성한 것이 아니에요. 사실, 의미 있는 원시 값이 없는 경우에는 원시 값을 제공할 필요가 없습니다.

enum Suit {
    case spades, hearts, diamonds, clubs
 
    func simpleDescription() -> String {
        switch self {
        case .spades:
            return "spades"
        case .hearts:
            return "hearts"
        case .diamonds:
            return "diamonds"
        case .clubs:
            return "clubs"
        }
    }
}
 
let hearts = Suit.hearts
let heartsDescription = hearts.simpleDescription()
swift

위의 예시에서 열거형의 hearts 케이스가 참조되는 두 가지 방식에 주목해 주세요. hearts 상수에 값을 할당할 때는 상수에 명시적인 유형이 지정되어 있지 않기 때문에 열거형 케이스 Suit.hearts가 전체 이름으로 참조됩니다. 반면에 switch 문 내부에서는 self의 값이 이미 한 벌(suit)임을 알고 있기 때문에 축약형 .hearts로 참조되고 있어요. 값의 유형을 이미 알고 있을 때는 언제든지 축약형을 사용할 수 있습니다.

열거형에 원시 값이 있는 경우, 해당 값은 선언의 일부로 결정되는데, 이는 특정 열거형 케이스의 모든 인스턴스가 항상 동일한 원시 값을 가짐을 의미해요. 열거형 케이스에 대한 또 다른 선택은 케이스와 연관된 값을 가지는 것입니다. 이러한 값은 인스턴스를 생성할 때 결정되며, 열거형 케이스의 각 인스턴스마다 다를 수 있어요. 연관 값은 열거형 케이스 인스턴스의 저장 속성처럼 동작한다고 생각할 수 있습니다. 예를 들어, 서버에 일출 및 일몰 시간을 요청하는 경우를 생각해 보세요. 서버는 요청된 정보로 응답하거나, 무엇이 잘못되었는지에 대한 설명으로 응답할 수 있습니다.

enum ServerResponse {
    case result(String, String)
    case failure(String)
}
 
let success = ServerResponse.result("6:00 am", "8:09 pm")
let failure = ServerResponse.failure("Out of cheese.")
 
switch success {
case let .result(sunrise, sunset):
    print("Sunrise is at \(sunrise) and sunset is at \(sunset).")
case let .failure(message):
    print("Failure...  \(message)")
}
// "Sunrise is at 6:00 am and sunset is at 8:09 pm."을 출력합니다.
swift

일출 및 일몰 시간이 switch 케이스에 대해 값을 매칭하는 과정의 일부로 ServerResponse 값에서 어떻게 추출되는지 주목해 주세요.

구조체를 생성하려면 struct를 사용하세요. 구조체는 메서드와 이니셜라이저를 포함하여 클래스와 동일한 많은 동작을 지원합니다. 구조체와 클래스의 가장 중요한 차이점 중 하나는 구조체는 코드에서 전달될 때 항상 복사되지만, 클래스는 참조로 전달된다는 것이에요.

struct Card {
    var rank: Rank
    var suit: Suit
    func simpleDescription() -> String {
        return "The \(rank.simpleDescription()) of \(suit.simpleDescription())"
    }
}
 
let threeOfSpades = Card(rank: .three, suit: .spades)
let threeOfSpadesDescription = threeOfSpades.simpleDescription()
swift

이렇게 Swift에서 열거형과 구조체를 사용하는 방법에 대해 알아보았습니다. 열거형은 관련된 값의 그룹을 정의하고 연관된 값을 가질 수 있으며, 구조체는 값 타입으로 데이터와 동작을 캡슐화할 수 있어요. 이러한 기능들은 코드의 구조와 명확성을 향상시키는 데 도움을 줍니다.