
- 스위프트는 안정성을 강조하는 언어인 만큼, 타입에 굉장히 민감하고 엄격하다.
- 서로 다른 타입끼리의 데이터 교환은 꼭 타입캐스팅을 거쳐야한다.
❗️ 스위프트에서 값 타입의 데이터 교환은 엄밀히 말하면 타입 캐스팅이 아닌 새로운 인스턴스를 할당하는 것.
스위프트는 데이터 타입을 안심하고 사용할 수 있는, Type-safte 언어이다. 스위프트가 컴파일 시 타입을 확인하는 것을 타입 확인이라고 한다.
- 스위프트에서는 변수나 상수를 선언할 때 특정 타입을 명시하지 않아도 컴파일러가 할당된 값을 기준으로 변수나 상수의 타입을 결정한다.
❗️빈 배열을 만들 경우에는 타입을 반드시 명시해야 한다.
스위프트에서 기본으로 제공하는 데이터 타입이든, 사용자가 임의로 만든 데이터 타입이든, 이미 존재하는 데이터 타입에 임의로 다른 이름(별칭)을 부여할 수 있다.
typealias MyInt = Int
typealias YourInt = Int
typealias MyDouble = Double
let age: MyInt = 100
var year: YoutInt = 2080
year = age
let month: Int = 7
let percentage: MyDouble = 99.9
- 튜플은 타입의 이름이 따로 지정되어 있지 않은, 프로그래머 마음대로 만드는 타입이다. 지정된 데이터의 묶음이라고 표현할 수 있다.
- C언어를 예로 들자면 원시 구조체의 형태와 가깝다.
- 튜플은 타입 이름이 따로 없으므로 일정 타입의 나열만으로 튜플 타입을 생성해줄 수 있다.
var person: (String, Int, Double) = ("toma", 100, 182.5)
// 인덱스를 통해서 값을 빼오고, 할당할 수도 있다.
person.1 = 99
person.2 = 178.5
이렇게 인덱스를 통해 요소에 접근 할 수 있지만, 차후에 각 요소의 어떤 의미가 있는지 유추하기가 어렵다는 점이 있다.
그래서 튜플의 요소마다 이름을 붙여줄 수도 있다.
var person: (name: String, age: Int, height: Double) = ("toma", 100, 182.5)
person.age = 99
person.2 = 178
이런식으로 하면 이름으로도, 인덱스로도 접근이 가능하다.
참고
Swift에서 튜플은 Collection type이 아니다!
Swift에서 타입은 크게named type과compound type이 존재하는데,named type은 우리가 주로 알고있는 기본타입들 외에도 enum, class, struct와 collection type들이 이에 해닿되고comound type에 tuple이 해당된다!
- 많은 수의 데이터를 묶어서 저장하고 관리할 수 있는 데이터 타입
- 배열, 딕셔너리, 세트 등이 있다.
- 배열은 같은 타입의 데이터를 일렬로 나열한 후 순서대로 저장하는 형태의 컬렉션 타입
- 각기 다른 위치에 같은 값이 들어갈 수도 있다.
first, last 프로퍼티로 접근index(of:) 메서드로 해당 요소의 인덱스를 알아낼 수 있다.append(_:) 메서드append(contentsOf:) 메서드insert(_:,at:) 메서드remove(_:)메서드를 사용var names: Array<String> = ["yagom", "toma", "swift", "toma"]
var names: [String] = ["yagom", "toma", "swift", "toma"]
var emptyArray: [Any] = [Any]()
var emptyArray: [Any] = Array<Any>() // 위와 동일한 의미의 코드
- 요소들이 순서없이 키와 값의 쌍으로 구성되는 컬렉션 타입이다.
- 딕셔너리에 저장되는 값은 항상 키와 쌍을 이룬다.
- 하나의 딕셔너리에서는 같은 키의 이름이 중복될 수 없다.
즉, 딕셔너리에서 키는 값을 대변하는 유일한 식별자이다.
typealias StringIntDictionary = [String: Int]
// 모두 같은 의미의 코드
var numberForName: Dictionary<String: Int> = Dictionary<String, Int>() // 빈 딕셔너리 생성
var numberForName: [String: Int] = [String: Int]()
var numberForName: StringIntDictionary =StringIntDictionary()
var numberForName: [String: Int] = [:]
- 같은 타입의 데이터를 순서없이 하나의 묶음으로 저장하는 형태의 컬렉션 타입이다.
- 세트 내의 값은 모두 유일한 값, 즉 중복된 값이 존재하지 않는다.
- 보통 순서가 중요하지 않거나, 각 요소가 유일한 값이어야 하는 경우 사용한다.
- 세트의 요소로는 *해시가능한 값이 들어와야한다.
→해시가능한 값이란 스위프트 표준 라이브러리의Hashable 프로토콜을 따른다는 것을 의미. 스위프트의 기본 데이터 타입은 모두 해시가능한 값.
insert(:_)remove(:_)intersection(:_).symmetricDifference(:_).union(:_).subtracting(:_)sorted() 메서드를 통해 정렬된 배열을 반환할 수 있다.세트는 포함관계를 연산할 수 있는 메서드로 구현되어있다.
isDisjoint(with:)isSubset(of:)isSuperSet(of)
- 연관된 항목들을 묶어서 표현할 수 있는 타입이다.
- 배열이나 딕셔너리 같은 타입과 다르게 프로그래머가 정의해준 값 외에는 추가/수정이 불가하다.
- 딱 정해진 값만 열거형 값에 속할 수 있다.
- 기존 C 언어 등에서 열거형은 주로 정수 타입 값의 별칭 형태로 사용될 뿐이었지만, 스위프트의 열거형은 각 열거형이 고유의 타입으로 인정된다.
열거형은 다음과 같은 경우 요긴하게 사용될 수 있다.
enum키워드로 선언
enum School {
case primary
case elementary
case middle
case high
case collage
case university
case graduate
}
// 같은 의미
enum School {
case primary, elementary, middle, high, collage, university, graduate
}
var highhestEducationLevel: School = School.university
var highhestEducationLevel: School = .university // 같은 의미
rawValue 프로퍼티를 통해 원시 값 사용 가능enum Numbers: Int {
case zero // rawValue = 0
case one // rawValue = 1
case two // rawValue = 2
case ten = 10 // rawValue = 10
}
일부 항목만 원시값을 주는 것도 가능하다.
나머지는 스위프트가 자동처리해준다.
enum MainDish {
case pasta(taste: String)
case pizza(dough: Stirng, topping: String)
case chicken(withSauce: Bool)
case rice
}
var dinner: MainDish = MainDish.pasta(taste: "크림")
dinner = .pizza(dough: "치즈 크러스트", topping: "불고기")
CaseIterable 프로토콜을 채택하면 열거형의 allCases 프로퍼티로 모든 케이스의 컬렉션을 생성할 수 있다.
indirect 키워드를 사용한다.enum ArithmeticExpression {
case number(Int)
indirect case addition(ArithmeticExpression, ArithmeticExpression)
indirect case multiplication(ArithmeticExpression, ArithmeticExpression)
}
// enum 자체에 키워드 붙이기도 가능
indirect enum ArithmeticExpression {
case number(Int)
case addition(ArithmeticExpression, ArithmeticExpression)
case multiplication(ArithmeticExpression, ArithmeticExpression)
}
Comparable 프로토콜을 준수하는 연관 값만 갖거나,Comparable 프로토콜을 채택하면 각 케이스를 비교할 수 있다.