- 스위프트는 안정성을 강조하는 언어인 만큼, 타입에 굉장히 민감하고 엄격하다.
- 서로 다른 타입끼리의 데이터 교환은 꼭 타입캐스팅을 거쳐야한다.
❗️ 스위프트에서 값 타입의 데이터 교환은 엄밀히 말하면 타입 캐스팅이 아닌 새로운 인스턴스를 할당하는 것.
스위프트는 데이터 타입을 안심하고 사용할 수 있는, 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
프로토콜을 채택하면 각 케이스를 비교할 수 있다.