Swift 둘러보기 (A Swift Tour) - 열거형과 구조체 (Enumerations and Structures)

00yhsp·2024년 3월 25일

열거형을 생성하기 위해서 enum을 사용한다.
클래스, 다른 명명된 타입과 같이 열거형을 메소드를 가질 수 있다.

enum Rank: Int {
	case ace = 1
    case two, three, four, five, six, seven, eight, nine, ten
    case jack, queen, king
    
    func simple Description() -> 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는 0을 시작으로 매번 증가하는 원시값(raw value)를 할당하지만,
명시적으로 특정 값으로 이 동작을 변경할 수 있다.
위의 예제에서 Ace는 명시적으로 1의 값이 주어지고, 나머지 원시값은 순서대로 할당된다.(1부터 시작)
열거형의 원시 타입으로 문자열 또는 부동 소수점 또한 사용할 수 있다.
열거형 케이스의 원시값에 접근하기 위해 rawValue 프로퍼티를 사용한다.

원시값으로부터 열거형의 인스턴스를 생성하기 위해 init?(rawValue:) 의 초기화 구문을 사용한다.
원시값이 일치하는 열거형 케이스나 Rank에 일치하는 항목이 없으면 nil을 반환한다.

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

열거형의 케이스 값은 원시값을 작성하는 다른 방법이 아니라 실제 값이다.
의미 없는 원시값 케이스의 경우 제공할 필요가 없다.

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()

위에서 열거형의 hearts 케이스를 참조하는 두 가지 방법:
hearts 상수에 값을 할당할 때 명시적으로 타입을 지정하지 않았으므로 열거형 케이스 Suit.hearts 전체 이름으로 참조된다.
스위치에서 self의 값은 이미 카드(suit)로 알고 있기 때문에, 열거형 케이스는 짧은 형식인 .hearts로 참조된다.
값의 타입을 이미 알고 있다면 언제나 짧은 형식을 사용할 수 있다.

열거형이 원시값을 갖는 경우 선언의 부분으로 결정된다.
이것은 특정 열거형 케이스의 모든 인스턴스는 항상 같은 원시값을 가진다는 의미이다.
열거형 케이스의 또 다른 선택은 케이스와 연관된 값(associated value)를 가지는 것이다.
이러한 값은 인스턴스 생성 시 결정되고, 열거형 케이스의 각 인스턴스에 대해 다를 수 있다.
연관된 값은 열거형 케이스 인스턴스의 저장된 프로퍼티처럼 동작한다고 생각할 수 있다.
예를 들어 서버에서 일출과 일몰 시간에 대해 요청한다면,
서버는 요청된 정보에 대한 응답을 하거나 무엇이 잘못되었는지에 대한 설명을 응답한다.

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)")
// Prints "Sunrise is at 6:00 am and sunset is at 8:09 pm."

구조체를 생성하기 위해 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 threeOfSpadesDesription = threeOfSpades.simpleDescription()
profile
iOS Dev

0개의 댓글