Swift의 자료형을 알아봅시다.
자료형은 데이터타입이라고도 불리고, 데이터의 종류를 뜻합니다.
Swift에서의 기본 자료형은 구조체를 기반으로 되어있습니다.
구조체는 클래스와 다르게 상속이 불가능하지만 프로토콜과 익스텐션을 통해 공통 기능 및 함수를 추가하거나 등 활용이 가능합니다.
Swift의 모든 데이터 타입이름은 대문자 카멜케이스를 사용합니다.
ex) Swift -> Int, Double, String
정수타입은 크게 Int, UInt 로 나누어서 볼 수 있습니다.
Int는 +, -, 0 을 모두 포함하는 정수타입이고, UInt는 0을 포함한 + 부호의 정수를 포함합니다.
Int와 UInt는 각각 8, 16, 32, 64비트의 형태가 있습니다.
ex) Int8, Int16, Int32, Int64, UInt8, UInt16, UInt32, UInt64
기본으로 Int, UInt 자료형은 시스템 아키텍쳐에 따라 달라집니다.
32비트 아키텍쳐를 사용하고있다면, Int -> Int32, UInt -> UInt32 이고,
64비트라면 Int -> Int64, UInt -> UInt64 타입으로 지정됩니다.
각각의 최댓값과 최솟값을 한번 알아봅시다.
print("\(Int8.min) ~ \(Int8.max)") // -128 ~ 127
print("\(UInt8.min) ~ \(UInt8.max)") // 0 ~ 255
print("\(Int16.min) ~ \(Int16.max)") // -32768 ~ 32767
print("\(UInt16.min) ~ \(UInt16.max)") // 0 ~ 65535
print("\(Int32.min) ~ \(Int32.max)") // -2147483648 ~ 2147483647
print("\(UInt32.min) ~ \(UInt32.max)") // 0 ~ 4294967295
print("\(Int64.min) ~ \(Int64.max)") // -9223372036854775808 ~ 9223372036854775807
print("\(UInt64.min) ~ \(UInt64.max)") // 0 ~ 18446744073709551615
print("\(Int.min) ~ \(Int.max)") // -9223372036854775808 ~ 9223372036854775807
print("\(UInt.min) ~ \(UInt.max)") // 0 ~ 18446744073709551615
진수에 따라 정수를 표현하는 방법도 있습니다.
let decimalInt: Int = 28
let binaryInt: Int = 0b11100
let octalInt: Int = 0o34
let hexadecimalInt: Int = 0x1c
print(decimalInt) // 28
print(binaryInt) // 28
print(octalInt) // 28
print(hexadecimalInt) // 28
String(_ value: BinaryInteger, radix: Int, uppercase: Bool) -> String
함수를 사용해서 진수에 맞는 문자열을 얻을 수도 있습니다.
let decimalInt: Int = 28
let binaryInt: Int = 0b11100
let octalInt: Int = 0o34
let hexadecimalInt: Int = 0x1c
let transBinary = String(decimalInt, radix: 2, uppercase: false)
let transOctal = String(decimalInt, radix: 8, uppercase: false)
let transHexadecimal = String(decimalInt, radix: 16, uppercase: false)
print(transBinary) // 11100
print(transOctal) // 34
print(transHexadecimal) // 1c
불리언 타입은 Bool로 표현하고, true(참) 또는 false(거짓)만 값으로 가집니다.
var boolean: Bool = true
print(boolean) // true
boolean.toggle() // true - false 반전
print(boolean) // false
부동소수점을 사용하는 부동소수 타입이 있습니다.
Double, Float 두 자료형이 있는데 Double 자료형은 64비트의 부동소수 표현을하고, 최소 15자리의 십진수를 표현할 수 있습니다. 반면에 Float 자료형은 32비트의 부동소수 표현을하고, 최소 6자리의 숫자까지만 표현이 가능합니다.
let floatValue: Float = 1234567890.1
let doubleValue: Double = 1234567890.1
print(floatValue) // 1.234568e+09
print(doubleValue) // 1234567890.1
Float 자료형인데 6자리 이상을 표현해주었기 때문에 정확도가 떨어집니다.
부동소수 자료형인데 e가 나타나서 이상해보일 수 있지만 이는 10진수의 제곱을 뜻합니다.
var doubleValue = 1.23e5
print(doubleValue) = 123000.0
// 1.23e5 = 1.23 * 10^5 == 123000.0
doubleValue = 1.23e-3
print(doubleValue) = 0.00123
// 1.23e-3 = 1.23 * 10^-3 == 0.00123
문자 타입은 Character로 표현합니다.
단어가 아닌 단 하나의 문자를 의미합니다.
영어, 특수기호, 이모티콘 등을 사용할 수 있습니다.
let word: Character = "a"
print(word) // a
let korea: Character = "🇰🇷"
print(korea) // 🇰🇷
물론 한글도 사용할 수 있습니다.
let 디귿: Character = "ㄷ"
print(디귿) // ㄷ
문자열을 말 그대로 문자들의 나열이며 String으로 표현합니다.
append(), + 를 통해서 문자열을 이어 붙일 수 있고, count를 통해서 문자열의 길이를 셀 수 있습니다.
또한 isEmpty, last 등등 다양한 기능을 사용할 수 있습니다.
var name: String = "만도스"
print("안녕하세요 " + name + "입니다.") // 안녕하세요 만도스입니다.
print(name.count) // 3
기존 파이썬등 다른언어와 달리 Swift에서 문자열은 인덱싱으로 접근할 수 없습니다.
다른 언어와 마찬가지로 String은 구조체 타입이고, Character의 Array 입니다.
C++이나 Java의 경우에는 char 타입은 고정된 크기를 갖지만 Swift 에서는 Character는 1개 이상의 유니코드 스칼라로 이루어져 있는데, 이는 크기가 가변적이라고 할 수 있습니다.
string 하나의 값에 유니코드 스칼라, utf-16, utf-8 등 다양한 뷰를 제공하기 때문에, 단순히 Int 타입으로 서브스크립트에 접근하기에는 어떠한 뷰를 기준으로 인덱싱을 지원해야 하는지 애매하기 떄문에 접근이 불가능 하고, String.Index 라는 구조체를 별도로 제공하여 인덱싱을 지원합니다.
let korea: Character = "🇰🇷"
print(korea.unicodeScalars.count) // 2
print(korea.utf8.count) // 8
print(korea.utf16.count) // 4
let hello: String = "Hello Swift!"
let fifthIndex = hello.index(hello.startIndex, offsetBy: 4)
print(hello[fifthIndex]) // o
print(hello[hello.startIndex...fifthIndex]) // Hello
Swift에서는 문자열 내에서 일정 기능을 하는 특수문자(제어문자)가 있습니다.
특수문자는 백슬레시에 특정한 문자를 조합하여 사용합니다.
특수문자 | 설명 |
---|---|
\n | 줄바꿈 문자 |
\\ | 문자열 내에 백슬레시(\) 를 표현할 때 사용 |
\" | 문자열 내에 큰따옴표(") 표현할 때 사용 |
\t | 키보드의 탭키를 눌렀을 때와 같은 효과 |
\O | 문자열이 끝났음을 알리는 null 문자 |
Any는 스위프트의 모든 데이터 타입을 사용할 수 있다는 뜻입니다.
Any로 지정된 변수, 또는 상수가 있다면 그 변수나 상수에는 어떤 종류의 데이터 타입이 들어가든지 상관이 없습니다.
AnyObject는 Any 보다는 조금 한정된 의미이며, 클래스의 인스턴스만 할당할 수 있습니다.
var anythingValue: Any = "만도스"
print(anythingValue) // 만도스
anythingValue = 7
print(anythingValue) // 7
anythingValue = false
print(anythingValue) // false
타입을 분명히 하는것보다 Any를 사용하는게 더 편하지 않을까라는 생각을 하실 수 있습니다. 하지만 Any, AnyObject 사용하지않는 편이 좋습니다. Swift는 안전한 프로그래밍을 지향하기 때문에 타입을 엄격히 하고 있습니다. 그렇기 때문에 Any, AnyObject로 선언된 변수의 값을 쓰기위해서는 타입을 확인해주거나 변환해주어야 하고, 이는 예상치 못한 오류의 위험을 증가시키기 때문입니다.
var anythingValue: Any = true
if anythingValue as! Bool {
print("타입을 명확히 해줘야함..")
}
if type(of: anythingValue) == Bool.self {
print("??")
}
nil은 특정 타입은 아니고, "없음"을 나타내는 키워드 입니다.
Swift는 값이 있거나 없거나를 표현하는 옵셔널이라는게 있는데 옵셔널에 대해 공부할 때 자세히 알아보도록 하겠습니다.