스위프트의 데이터 타입
2022/12/07(수요일)
[스위프트]
4.1 데이터 타입 안심
애플이 처음 스위프트를 발표할 때 강조했던 스위프트의 특징 중 안정성(safe)이 가장 뚜렷하게 나타나는 부분이다. 스위프트는 타이벵 굉장히 민감하고 엄격하다. 서로 다른 타입끼리의 데이터 교환은 꼭 타입캐스팅을 거쳐야 한다. 스위프트에서 값 타입의 데이터 교환은 엄밀히 말하면 타입캐스팅이 아닌 새로운 인스턴스를 생성하여 할당하는 것이다.
4.1.1 데이터 타입 안심이란?
스위프트는 데이터 타입을 안심하고 사용할 수 있는(Type-safe)언어이다. 타입을 안심하고 사용할 수 있다는 말은 그만큼 실수를 줄일 수 있다는 의미이다. 예를 들어 Int 타입 변수에 할당하려는 값이 Character 타입이라면 컴파일 오류가 발생한다. 이런 오류는 프로그래밍 도중에 눈치채기 어려워 컴파일러가 알려주지 않으면 나중에 오류를 찾아내기도 쉽지 않다. 그렇지만 스위프트는 컴파일 오류로 알려주므로 서로 다른 타입의 값을 할당하는 실수를 줄일 수 있다. 이렇게 스위프트가 컴파일 시 타입을 확인하는 것을 타입 확인이라고 한다. 타입 확인을 통해 여러 타입을 섞어 사용할 때 발생할 수 있는 런타임 오류를 피할 수도 있다.
4.1.2 타입 추론
스위프트에서는 변수나 상수를 선언할 때 특정 타입을 명시하지 않아도 컴파일러가 할당된 값을 기준으로 변수나 상수의 타입을 결정한다. 예를 들어 let name = “hyungjun” 라는 코드를 작성하면, 컴파일러가 컴파일하면서 name의 타입을 String으로 결정한다.
// 타입을 지정하지 않았으나 타입 추론을 통하여 name은 String 타입으로 선언된다.
var name = "Hyungjun"
// 앞서 타입 추론에 의해 name은 String 타입의 변수로 지정되었기 때문에
// 정수를 할당하려고 시도하면 오류가 발생한다.
name = 100
4.2 타입 별칭
스위프트에서 기본적으로 제공하는 데이터 타입이든, 사용자가 임의로 만든 데이터 타입이든 이미 존재하는 데이터 타입에 임의로 다른 이름 (별칭) 을 부여할 수 있다. 그런 다음 기본 타입 이름과 이후에 추가한 별칭을 모두 사용할 수 있다. 아래 코드를 보면 쉽게 이해할 수 있을 것이다.기존에 사용하던 데이터 타입의 이름과 프로그래머가 만들어준 이름 모두 사용할 수 있다.
typealias MyInt = Int
typealias YourInt = Int
typealias MyDouble = Double
let age: MyInt = 100 // MyInt는 Int의 또 다른 이름이다.
var year: YourInt = 2000 // YourInt도 Int의 또 다른 이름이다.
// MyInt, YourInt 모두 Int이기 때문에 같은 타입으로 취급한다.
year = age
let month: Int = 7 // 물론 기존의 Int도 사용가능하다.
let percentage: MyDouble = 99.9 // Int 외에 다른 자료형도 모두 별칭 사용 가능하다.
4.3 튜플
튜플(Tuple)은 타입의 이름이 따로 지정되어 있지 않은, 프로그래머 마음대로 만드는 타입이다. ‘지정된 데이터의 묶음’이라고 표현할 수 있다. C 언어를 예로 들자면 원시 구조체의 형태와 비슷하다.
스위프트의 튜플은 파이썬의 튜플과 유사하다. 튜플은 타입 이름이 따로 없으므로 일정 타입의 나열만으로 튜플 타입을 생성해줄 수 있다. 튜플에 포함될 데이터의 개수는 자유롭게 정할 수 있다. 하나가 될 수도, 두 개가 될 수도, 여러개가 될 수도 있다.
// String, Int, Double 타입을 갖는 튜플
var person: (String, Int, Double) = ("lhj", 24, 174.4)
// 인덱스를 통해서 값을 빼 올 수 있다.
print("이름 : \(person.0), 나이 : \(person.1), 신장 : \(174.4)")
person.1 = 99
person.2 = 188.4 // 인덱스를 통해 값을 할당할 수 있다.
위의 코드에서 튜플은 각 요소를 이름 대신 숫자로 표현하기 때문에 간편해 보일 수 있지만, 차후에 다른 프로그래머가 코드를 볼 때 각 요소가 어떤 의미가 있는지 유추하기가 어렵다. 이름 없이 인덱스만으로 각 요소으 ㅣ데이터가 무엇을 나타내는지 쉽게 파악하기가 어렵기 때문이다. 그래서 튜플의 요소마다 이름을 붙여줄 수 도 있다. 아래 코드에서는 튜플의 요소마다 이름을 붙인 것이다.
// String, Int, Double 타입을 갖는 튜플
var person: (name: String, age: Int, height: Double) = ("lhj", 24, 174.4)
// 요소 이름ㅇ르 통해서 값을 빼 올 수 있다.
print("이름 : \(person.name), 나이 : \(person.age), 신장 : \(person.height)")
person.age = 99 // 요소 이름을 통해 값을 할당할 수 있다.
person.2 = 188.4 // 인덱스를 통해서도 값을 할당할 수 있다.
// 기존 처럼 인덱스를 이용하여 값을 빼 올 수도 있다.
print("이름 : \(person.0), 나이 : \(person.1), 신장 : \(174.4)")
또, 튜플에는 타입 이름에 해당하는 키워드가 따로 없다 보니 사용에 불편함을 겪기도 한다. 매번 같은 모양의 튜플을 사용하고 싶은데 선언해줄 때마다 긴 튜플 타입을 모두 써줘야 하는 불편함이 생길 수 있기 때문이다. 이럴 때는 타입 별칭을 사용하여 조금 더 깔끔하고 안전하게 코드를 작성할 수 있다.
typealias PersonTuple = (name: String, age: Int, height: Double)
let lhj: PersonTuple = ("lhj", 24, 174.4)
let jhl: PersonTuple = ("jhl", 24, 188.4)
print("이름 : \(lhj.name), 나이 : \(lhj.age), 신장 : \(lhj.height)")
print("이름 : \(jhl.name), 나이 : \(jhl.age), 신장 : \(jhl.height)")