타입 별칭
사용자가 임의로 만든 데이터 타입이든 이미 존재하는 데이터 타입에 임의로 다른 이름을 부여할 수
있다.
typealias MyInt = Int
typealias MyDouble = Double
let age: MyInt = 24
let percentage: MyDouble = 25.5
튜플
- 타입의 이름이 따로 지정되어 있지 않은, 프로그래머 마음대로 만드는 타입.
- 지정된 데이터의 묶음
// String, Int, Double 타입을 갖는 튜플
var person: (String, Int, Double) = ("SDY", 100, 55.5)
// 인덱스를 통해서 값을 빼 올 수 있다.
print("이름: \(person.0), 나이: \(person.1), 몸무게: \(person.2)")
// 인덱스를 통해 값을 할당할 수 있다.
person.1 = 99
person.2 = 60.5
튜플 요소 이름 지정
// String, Int, Double 타입을 갖는 튜플
var person: (name: String, age: Int, weight: Double) = ("SDY", 100, 55.5)
// 요소 이름을 통해서 값을 빼 올 수 있다.
print("이름: \(person.name), 나이: \(person.age), 몸무게: \(person.weight)")
튜플 별칭 지정
typealias PersonTuple = (name: String, age: Int, height: Double)
let sdy: PersonTuple = ("sdy", 100, 55.5)
print("이름: \(sdy.name), 나이: \(sdy.age), 몸무게: \(sdy.weight)")
* 스위프트는 튜플 외에도 많은 수의 데이터를 묶어서 저장하고 관리할 수 있는 컬렉션 타입(배열, 딕셔너리, 세트)을 제공한다.
배열
- 같은 타입의 데이터를 일렬로 나열한 후 순서대로 저장하는 형태의 컬렉션 타입
- Array 키워드와 타입 이름의 조합으로 사용
- 스위프트의 Array는 필요에 따라 자동으로 버퍼의 크기를 조절해주므로 요소의 삽입 및 삭제가 용이
// 대괄호를 사용하여 배열임을 표현
var names: Array<String> = ["sdy","kcs","kyh"]
// 위 선언과 정확히 동일한 표현, [String]은 Array<String>의 축약 표현
var names: [String] = ["sdy","kcs","kyh"]
var emptyArray: [Any] = [Any]() // Any 데이터를 요소를 갖는 빈 배열을 생성
var emptyArray: [Any] = Array<Any>() // 위 선언과 정확히 같은 동작을 하는 코드
// 배열의 타입을 정확히 명시해줬다면 []만으로도 빈 배열을 생성 가능
var emptyArray: [Any] = []
print(emptyArray.isEmpty) // true
print(names.count) // 3
// 요소 추가
names.append("elsa")
names.append(contentsOf: ["john", "max"])
names.insert("happy", at: 2)
names.insert(contentsOf: ["kjh","kms"], at: 3)
print(names.firstIndex(of: "sdy")) // 0
print(names.firstIndex(of: "christal")) // nil
print(names.first) // sdy
print(names.last) // max
let firstItem: String = names.removeFirst()
let lastItem: String = names.removeLast()
let indexZeroItem: String = names.remove(at: 0)
print(firstItem) // sdy
print(lastItem) // max
print(indexZeroItem) // kcs
- 빈 배열은 이니셜라이저 또는 리터널 문법을 통해 생성
- 배열에 몇 개의 요소가 존재하는지 알고 싶으면 count 프로퍼티를 확인
- 맨 처음과 맨 마지막 요소는 first와 last 프로퍼티를 통해 가져올 수 있다.
- firstIndex(of:) 메서드를 사용하면 해당 인덱스를 알아낼 수 있다. (중복된 요소가 있다면 제일 먼저 발견된 요소의 인덱스를 반환)
- 맨 뒤에 요소를 추가하고 싶다면 append(_:) 메서드를 사용
- 중간에 요소를 삽입하고 싶다면 insert(_:at:) 메서드를 사용
- 요소를 삭제하고 싶다면 remove(_:) 메서드를 사용하게 되는데, 메서드를 사용하면 해당 요소가 삭제된 후 반환
딕셔너리
- 요소들이 순서 없이 키와 값의 쌍으로 구성되는 컬렉션 타입
- 키는 같은 이름을 중복해서 사용할 수 없다.
- 딕셔너리는 Dictionary라는 키워드와 키의 타입과 값의 타입 이름의 조합으로 쓴다.
- 빈 딕셔너리는 이니셜라이저 또는 리터럴 문법을 통해 생성 가능
- isEmpty 프로퍼티를 통해 비어있는 딕셔너리인지 확인 가능
- count 프로퍼티로 딕셔너리의 요소 개수를 확인 가능
// typealias를 통해 조금 더 단순하게 표현 가능
typealias StringIntDictionary = [String: Int]
// 키는 String, 값은 Int 타입인 빈 딕셔너리를 생성
var numberForName: Dictionary<String, Int> = Dictionary<String, Int>()
// 위와 같은 표현, [String: Int]는 Dictionary<String, Int>의 축약 표현
var numberForName: [String: Int] = [String: Int]()
// 위 코드와 같은 동작
var numberForName: StringIntDictionary = StringIntDictionary()
// 딕셔너리의 키와 값을 정확히 명시했다면 [:]만으로도 빈 딕셔너리를 생성 가능
var numberForName: [String: Int] = [:]
// 초기값을 주어 생성
var numberForName: [String: Int] = ["sdy": 100, "chulsoo": 200, "jenny": 300]
numberForName["chulsoo"] = 150 // chulsoo 라는 키를 가진 요소의 값을 변경
print(numberForName["chulsoo"]) // 150
numberForName["max"] = 999
print(numberForName["max"]) // 999
// sdy 키에 해당하는 값을 삭제하고 출력
print(numberForName.removeValue(forKey: "sdy")) // 100
// sdy 키에 해당하는 값이 없을 때 기본값(0)을 반환
print(numberForName["sdy", default: 0]) // 0
세트
- 같은 타입의 데이터를 순서 없이 하나의 묶음으로 저장하는 형태의 컬렙션 타입
- 세트 내의 값은 모두 유일한 값, 즉 중복된 값이 존재하지 않다.
- 보통 순서가 중요하지 않거나 각 요소가 유일한 값이어야 하는 경우에 사용
- 세트의 요소로 해시 가능한 값이 들어와야 한다.
- Set 키워드와 타입 이름의 조합으로 쓴다.
- 배열과 마찬가지로 대괄호로 값들을 묶어 세트 타입임을 표현
- 빈 세트는 이니셜라이저 또는 리터럴 문법을 통해 생성
- 세트에 요소틑 추가하고 싶다면 insert(_:) 메서드를 사용
- 요소를 삭제하고 싶다면 remove(_:) 메서드를 사용
// 빈 세트 생성
var names: Set<String> = Set<String>()
var names: Set<String> = []
// Array와 마찬가지로 대괄호를 사용하기 때문에 타입 추론을 사용하면 Array로 타입이 지정된다.
var names: Set<String> = ["sdy","chulsoo","younghee","sdy"]
names.insert("jenny")
print(names.remove("chulsoo")) // chulsoo
print(names.remove("john")) // nil
열거형
- 연관된 항목들을 묶어서 표현할 수 있는 타입
- 프로그래머가 정의해준 항목 값 외에는 추가, 수정이 불가
- 스위프트의 열거형은 각 열거형이 고유의 타입을 가진다.
- 열거형 각 항목이 원시 값(Raw Value)이라는 형태로 (정수, 실수, 문자 타입의) 실제 값을 가질 수 있다.
- 연관 값(Associated Values)을 사용하여 값의 묶음도 구현할 수 있다.
열거형의 선언
enum School {
case primary
case elementary
case middle
case high
// 한 줄로 모두 표현 가능
// case primary, elementary, middle, high
}
열거형 변수의 생성 및 값 변경
var highestEducationLevel: School = School.high
// 위 코드와 같은 표현
var highestEducationLevel: School = .high
highestEducationLevel = .middle
원시 값
- 특정 타입으로 지정된 값을 가질 수 있다.
- 열거형 이름 오른쪽에 타입을 명시
- 원시 값을 사용하고 싶을 때 rawValue 프로퍼티 사용
enum School: String {
case primary = "유치원"
case elementary = "초등학교"
case middle = "중학교"
case high = "고등학교"
case university = "대학교"
}
let educationLevel: School = School.university
print("저는 \(educationLevel)에 다니고 있습니다.")
// 저는 대학교에 다니고 있습니다.
연관 값
enum MainDish{
case pasta(taste: String)
case pizza(dough: String, topping: String)
case chicken(withSauce: Bool)
case rice
}
var dinner: MainDish = MainDish.pasta(taste: "크림")
dinner = .pizza(dough: "치즈크러스트", topping: "불고기")
응용
enum PastaTaste {
case cream, tomato
}
enum PizzaDough {
case cheeseCrust, thin, original
}
enum PizzaTopping {
case pepperoni, cheese, bacon
}
enum MainDish{
case pasta(taste: PastaTaste)
case pizza(dough: PizzaDough, topping: PizzaTopping)
}
var dinner: MainDish = MainDish.pasta(taste: PastaTaste.tomato)
dinner = .pizza(dough: PizzaDough.original, topping: PizzaTopping.cheese)
항목 순회
열거형에 포함된 모든 케이스를 알아야 할 때 CaseIterable 프로토콜 사용
enum School: CaseIterable{ // 원시값이 있는 경우 예): String, CaseIterable
case primary
case elementary
case middle
case high
case university
}
let allCases: [School] = School.allCases
print(allCases)
// [School.primary, School.elementary, School.middle, School.high, School.university]
순환 열거형
- 열거형 항목의 연관 값이 열거형 자신의 값이고자 할 때 사용
- 특정 항목에만 한정할 때 : case 키워드 앞에 indirect
- 열거형 전체에 적용할 떄 : enum 키워드 앞에 indriect
ArithmeticExpression 열거형을 사용하여 (5 + 4) x 2 연산을 구현하는 예제
indirect enum ArithmeticExpression {
case number(Int)
case addition(ArithmeticExpreesion, ArithmeticExpreesion)
case multiplication(ArithmeticExpreesion, ArithmeticExpreesion)
}
let five = ArithmeticExpreesion.number(5)
let four = ArithmeticExpreesion.number(4)
let sum = ArithmeticExpreesion.addition(five, four)
let final = ArithmeticExpreesion.multiplication(sum, ArithmeticExpreesion.number(2))
func evaluate(_ expression: ArithmeticExpreesion) -> Int {
switch expression {
case .number(let value):
return value
case .addition(let left, let right):
return evaluate(left) + evaluate(right)
case .multiplication(let left, let right):
return evaluate(left) * evaluate(right)
}
}
let result: Int = evaluate(final)
print("(5 + 4) * 2 = \(result)")
// (5 + 4) * 2 = 18
* evaluate는 ArithmeticExpression 열거형의 계산을 도화주는 순환 함수
비교 가능한 열거형
- Comparable 프로토콜을 준수하는 연관 값만 갖거나 연관 값이 없는 열거형은 Comparable 프로토콜을 채택하면 각 케이스를 비교할 수 있다.
- 앞에 위치한 케이스가 더 작은 값
비교 가능한 열거형의 사용
enum Condition: Comparable {
case terrible
case bad
case good
case great
}
let myCondition: Condition = Condition.great
let yourCondition: Condition = Condition.bad
if myCondition >= yourCondition {
print("제 상태가 더 좋아요")
} else {
print("당신 상태가 더 좋아요")
}
// 제 상태가 더 좋아요
[출처 : Swift 프로그래밍 야곰]
'Language > Swift' 카테고리의 다른 글
| Swift 네트워킹 방법 (0) | 2022.07.11 |
|---|---|
| Swift - 05 (0) | 2022.02.08 |
| Swift - 03 (0) | 2022.01.26 |
| Swift - 02 (0) | 2022.01.11 |
| Swift - 01 (0) | 2022.01.11 |
Comment