Enum(열거형) - switch-case와 쓰기, 메서드와 연동, 연동되는 값
22 Nov 2017 | enum swift열거형
리스트 형태로 정의된 여러 케이스로 인스턴스를 만들 수 있는 방법
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