Swift Language
열거 형
수색…
비고
struct와 마찬가지로 클래스와 달리 열거 형은 값 유형이며 전달 될 때 참조되는 대신 복사됩니다.
열거 형에 대한 자세한 내용은 Swift Programming Language를 참조하십시오.
기본 열거 형
열거 형 은 관련 값 집합을 제공합니다.
enum Direction {
case up
case down
case left
case right
}
enum Direction { case up, down, left, right }
Enum 값은 정규화 된 이름으로 사용할 수 있지만 유추 할 수있는 경우 유형 이름을 생략 할 수 있습니다.
let dir = Direction.up
let dir: Direction = Direction.up
let dir: Direction = .up
// func move(dir: Direction)...
move(Direction.up)
move(.up)
obj.dir = Direction.up
obj.dir = .up
enum 값을 비교 / 추출하는 가장 기본적인 방법은 switch
문을 사용하는 것입니다.
switch dir {
case .up:
// handle the up case
case .down:
// handle the down case
case .left:
// handle the left case
case .right:
// handle the right case
}
간단한 열거 형은 자동으로 Hashable
, Equatable
및 문자열 변환이 있습니다.
if dir == .down { ... }
let dirs: Set<Direction> = [.right, .left]
print(Direction.up) // prints "up"
debugPrint(Direction.up) // prints "Direction.up"
관련 지을 수 있었던 값을 가지는 열거 형
Enum 사례에는 하나 이상의 페이로드 ( 관련 값 )가 포함될 수 있습니다.
enum Action {
case jump
case kick
case move(distance: Float) // The "move" case has an associated distance
}
열거 형 값을 인스턴스화 할 때 페이로드가 제공되어야합니다.
performAction(.jump)
performAction(.kick)
performAction(.move(distance: 3.3))
performAction(.move(distance: 0.5))
switch
문은 연관된 값을 추출 할 수 있습니다.
switch action {
case .jump:
...
case .kick:
...
case .move(let distance): // or case let .move(distance):
print("Moving: \(distance)")
}
하나의 사례 추출을 사용하여 수행 할 수 있습니다 if case
:
if case .move(let distance) = action {
print("Moving: \(distance)")
}
guard case
구문은 추후 사용 추출을 위해 사용될 수 있습니다 :
guard case .move(let distance) = action else {
print("Action is not move")
return
}
연관된 값을 가진 Equatable
은 기본적으로 Equatable
이 아닙니다. ==
연산자의 구현은 수동으로 수행해야합니다.
extension Action: Equatable { }
func ==(lhs: Action, rhs: Action) -> Bool {
switch lhs {
case .jump: if case .jump = rhs { return true }
case .kick: if case .kick = rhs { return true }
case .move(let lhsDistance): if case .move (let rhsDistance) = rhs { return lhsDistance == rhsDistance }
}
return false
}
간접 하중
일반적으로 enum은 재귀 적이 될 수 없습니다 (무한한 저장 공간이 필요하기 때문에).
enum Tree<T> {
case leaf(T)
case branch(Tree<T>, Tree<T>) // error: recursive enum 'Tree<T>' is not marked 'indirect'
}
indirect
키워드는 열거 형 저장소를 인라인으로 저장하는 대신 간접적 인 계층으로 페이로드에 저장합니다. 이 키워드는 단일 사례에서 사용할 수 있습니다.
enum Tree<T> {
case leaf(T)
indirect case branch(Tree<T>, Tree<T>)
}
let tree = Tree.branch(.leaf(1), .branch(.leaf(2), .leaf(3)))
indirect
는 또한 전체 열거 형에서 작동하며 필요한 경우 간접적으로 사용합니다.
indirect enum Tree<T> {
case leaf(T)
case branch(Tree<T>, Tree<T>)
}
원시 및 해시 값
페이로드가없는 열거 형은 임의의 리터럴 유형의 원시 값 을 가질 수 있습니다.
enum Rotation: Int {
case up = 0
case left = 90
case upsideDown = 180
case right = 270
}
특정 유형이없는 열거 형은 rawValue 속성을 노출하지 않습니다.
enum Rotation {
case up
case right
case down
case left
}
let foo = Rotation.up
foo.rawValue //error
정수 원시 값은 0에서 시작하여 단조롭게 증가한다고 가정합니다.
enum MetasyntacticVariable: Int {
case foo // rawValue is automatically 0
case bar // rawValue is automatically 1
case baz = 7
case quux // rawValue is automatically 8
}
문자열 원시 값은 자동으로 합성 될 수 있습니다.
enum MarsMoon: String {
case phobos // rawValue is automatically "phobos"
case deimos // rawValue is automatically "deimos"
}
원시 값 열거 형은 자동으로 RawRepresentable 을 따릅니다 . .rawValue
하여 enum 값의 해당 원시 값을 .rawValue
.
func rotate(rotation: Rotation) {
let degrees = rotation.rawValue
...
}
init?(rawValue:)
사용하여 원시 값 에서 열거 형 을 만들 수도 있습니다.
let rotation = Rotation(rawValue: 0) // returns Rotation.Up
let otherRotation = Rotation(rawValue: 45) // returns nil (there is no Rotation with rawValue 45)
if let moon = MarsMoon(rawValue: str) {
print("Mars has a moon named \(str)")
} else {
print("Mars doesn't have a moon named \(str)")
}
특정 열거 형의 해시 값을 가져 오려면 hashValue에 액세스 할 수 있습니다. 해시 값은 열거 형의 인덱스를 0부터 시작합니다.
let quux = MetasyntacticVariable(rawValue: 8)// rawValue is 8
quux?.hashValue //hashValue is 3
초기화 기
열거 형은 기본 init?(rawValue:)
보다 유용 할 수있는 사용자 정의 init 메소드를 가질 수 있습니다. 열거 형은 값도 저장할 수 있습니다. 이것은 초기화 된 값을 저장하고 나중에 값을 검색하는 데 유용 할 수 있습니다.
enum CompassDirection {
case north(Int)
case south(Int)
case east(Int)
case west(Int)
init?(degrees: Int) {
switch degrees {
case 0...45:
self = .north(degrees)
case 46...135:
self = .east(degrees)
case 136...225:
self = .south(degrees)
case 226...315:
self = .west(degrees)
case 316...360:
self = .north(degrees)
default:
return nil
}
}
var value: Int = {
switch self {
case north(let degrees):
return degrees
case south(let degrees):
return degrees
case east(let degrees):
return degrees
case west(let degrees):
return degrees
}
}
}
초기화 프로그램을 사용하면 다음과 같이 할 수 있습니다.
var direction = CompassDirection(degrees: 0) // Returns CompassDirection.north
direction = CompassDirection(degrees: 90) // Returns CompassDirection.east
print(direction.value) //prints 90
direction = CompassDirection(degrees: 500) // Returns nil
열거 형은 클래스 및 구조와 많은 기능을 공유합니다.
Swift의 열거 형 언어는 C 와 같이 다른 언어로 작성된 일부 언어보다 훨씬 강력합니다. 초기화 메소드 , 계산 된 프로퍼티 , 인스턴스 메소드 , 프로토콜 준수 및 확장 과 같은 클래스 및 구조체 와 많은 기능을 공유 합니다 .
protocol ChangesDirection {
mutating func changeDirection()
}
enum Direction {
// enumeration cases
case up, down, left, right
// initialise the enum instance with a case
// that's in the opposite direction to another
init(oppositeTo otherDirection: Direction) {
self = otherDirection.opposite
}
// computed property that returns the opposite direction
var opposite: Direction {
switch self {
case .up:
return .down
case .down:
return .up
case .left:
return .right
case .right:
return .left
}
}
}
// extension to Direction that adds conformance to the ChangesDirection protocol
extension Direction: ChangesDirection {
mutating func changeDirection() {
self = .left
}
}
var dir = Direction(oppositeTo: .down) // Direction.up
dir.changeDirection() // Direction.left
let opposite = dir.opposite // Direction.right
중첩 된 열거 형
열거 형을 다른 열거 형 내에 중첩시킬 수 있으므로 계층 형 열거 형을 구조화하고 명확하게 구성 할 수 있습니다.
enum Orchestra {
enum Strings {
case violin
case viola
case cello
case doubleBasse
}
enum Keyboards {
case piano
case celesta
case harp
}
enum Woodwinds {
case flute
case oboe
case clarinet
case bassoon
case contrabassoon
}
}
그리고 당신은 그것을 다음과 같이 사용할 수 있습니다 :
let instrment1 = Orchestra.Strings.viola
let instrment2 = Orchestra.Keyboards.piano