공부 연습장 :-)

Enum(열거형) - switch-case와 쓰기, 메서드와 연동, 연동되는 값

|

열거형

리스트 형태로 정의된 여러 케이스로 인스턴스를 만들 수 있는 방법

enum은 한번 저장해(메모리에 올려)놓고 값을 변경해서 쓰지 않는 상수개념이기때문에 static변수처럼 쓰여 인스턴스 프로퍼티로 사용하면 컴파일에러가 난다! (스트럭트이름.enum타입) 으로 사용

열거형의 타입 추론

변수의 타입이 열거형이라는 것만 알고있으면 새 값을 대입할 때 타입을 생략할 수 있다.

...
var alignment = TextAlignment.left
alignment = .right

처음에 alignment변수를 만들때는 열거형의 타입과 값을 지정해야했지만, 그 다음 행부터는 타입을 생략하고 그 타입의 다른 값으로 지정할 수 있다. (값을 함수에 전달할때나 비교할 때도 열거형 생략 가능)

조건문을 switch로 쓰기

enum TextAlignment {
    case Left
    case Right
    case Center
    case Justify
}

alignment = .Right //타입 추론

if alignment == .Right { //비교할때도 타입추론 가능
    print("We should right-align the text!")
}

//열거형의 값을 if문에서 비교할 경우 보통 switch구문을 사용함
switch alignment {
case .Left: print("Left Aligned")
case .Right: print("Right Aligned")
case .Center: print("Center Aligned")
case .Justify: print("Justified")
}
  • switch - case를 쓸때 열거형에서는 default 케이스를 쓰지 않는 것이 좋다.(컴파일러가 이미 모든 가능한 값을 알고 있기때문에)

메서드

스위프트의 메서드는 열거형과도 연동된다.

// playground(전구켜기)

enum Lightbulb {
    case on
    case off

    func surfaceTemperature(forAmbientTemp ambient: Double)-> Double { //Lightbulb의 메서드
        switch self {
        case .on:
            return ambient + 150.0
        case .off:
            return ambient
        }   
    }   
}

var bulb = Lightbulb.on
let ambientTemperature = 100.0
let bulbOnTemperature = bulb.surfaceTemperature(forAmbientTemp: ambientTemperature)
print(bulbOnTemperature) // 250.0

surfaceTemperature함수는 enum타입의 Lightbulb 내부에 선언되어있으며, 전구가 켜져서 전구 표면의 온도가 올라가면 주변의 온도도 올라가는 것을 표현한 메서드이다.

  • self : self는 Lightbulb타입의 암묵적인 인수. 스위프트의 메서드는 예외없이 self인수를 가지는데, 이 self는 해당 메서드가 호출되는 인스턴스에 엑세스하는데 사용된다. 여기서는 Lightbulb의 인스턴스에 엑세스하는데 사용된다.
// playground(전구 켜고끄기)

enum Lightbulb {
    case on
    case off

...


// toggle()함수를 호출하면 전구가 on상태일때 off하고, off상태일때는 on.

   mutating func toggle() {
        switch self {
        case .on:
            self = .off
        case .off:
            self = .on
        }
    }
}

var bulb = Lightbulb.on
let ambientTemperature = 100.0
var bulbTemperature = bulb.surfaceTemperature(forAmbientTemp: ambientTemperature)
print(bulbTemperature)


bulb.toggle() // bulb는 .on상태였으니까 여기서 toggle을 호출해서 off상태로 바꿈
bulbTemperature = bulb.surfaceTemperature(forAmbientTemp: ambientTemperature)
print("after toggle: \(bulbTemperature)") // after toggle: 100.0

연동되는 값


enum ShapeDimensions {
    case square(side: Double)
    case rectangle(width: Double, height: Double)  

    func area() -> Double {
        switch self {
        case let .square(side: s):
            return s * s
        case let .rectangle(width: w, height: h):
            return w * h
        }
    }
}

// ShapeDimensions의 연동값을 만들려면 해당 케이스와 그에 따른 적절한 연동값을 지정해야한다.
var squareShape = ShapeDimensions.square(side: 10.0) // 한변 길이 10.0인 정사각형 생성
var squareShape2 = ShapeDimensions.square(side: 5.0) // 한변 길이 5.0인 정사각형 생성
print(squareShape.area()) // 100.0
print(squareShape2.area()) // 25.0
var rectangleShape = ShapeDimensions.rectangle(width: 5.0, height: 10.0) // 직사각형 생성
print(rectangleShape.area()) // 50.0
  • ShapeDimensions에서
    • 정사각형의 연동값은 한 변의 길이
    • 직사각형의 연동값은 그 너비와 높이 - 튜플로 width와 height
  • let: switch의 케이스들의 self의 연동값을 새 변수에 바인딩하기위해 사용. 연동값을 주고 그에 따라서 ShapeDimensions타입의 케이스를 만들어내는데, 주어진 연동값이 변동됐을때도 딱 그때 호출된 케이스에 제대로 바인딩된 값만 주려고 let으로 상수 바인딩을 시키는것! let이 없으면 컴파일에러가 나는데, 만약 var squareShape = ShapeDimensions.square(side: 10.0)var squareShape2 = ShapeDimensions.square(side: 5.0)처럼 연동값을 다르게 해서 호출했을때 바인딩을 안해주면 두 번 다 하나의 같은 연동값이 적용될수도 있다. 그래서 컴파일러가 막아놓은것 같음. (let은 어쨌든 연동값으로 들어온 s, w, h를 바인딩하기위함임. 내일 설명을 듣고 더 매끄럽게 정리해야겠다.) enum에 연관값이 있을때 연관값이 무엇인지도 알아야하고 그것을 사용하기 위해서는 한번 더 비교해서 값을 꺼낸다는 개념

Comments