Swift는 정적 타이핑 언어 입니다.
그게 무엇이냐? 변수나 상수를 정의할 때 그 자료형(타입)이 어떤 것인지 명시해주어야 하는 언어를 말합니다.
다른 언어와 마찬가지로 Swift도 상수, 변수가 존재하고,
상수는 let으로 표기하고, 변수는 var로 표기합니다.
상수가 뭔가요? 고정된 값입니다.
변수가 뭔가요? 변할 수 있는 값입니다.
굳이 상수와 변수로 나눠서 선언해주는 이유는 뭔가요?
상수와 변수 중 하나만 존재하게 되면, 고정된 값을 변수로 만들어서 변할 수 있는 여지를 줄 수 있고, 변해야하는 값을 고정시켜버려서 불편을 줄 수 있기 때문이 아닐까 싶습니다. 그래서 둘 다 필요한 거죠!
상수가 있기 때문에 고정된 값에 실수로 값을 넣어서 값이 변하는 불상사를 막아주기도 하기도 하고, 계속해서 새로운 값을 받는 변수가 있어서 변하는 값을 쓸 수도 있는거죠.
하지만 가장 큰 이유는
메모리 누수를 방지하기 위해서 입니다.
상수를 사용할 경우에는 변하지 않을 데이터의 메모리만 가지고 있으면 되지만, 변수는 변할 수 있는 가능성이 있기 때문에 메모리가 변할 수 있어요.
// 타입 어노테이션(annotation)
// Swift는 타입을 붙이고 사용하는 것이 안전하다.
// (키워드) (이름): (타입) = (값)
var number: Int = 2
// 타입 Inference, 타입 추론
// (키워드) (이름) = (값)
var number = 1.5
// 선언과 값 할당 분리 가능
// 상수에 값을 할당한 다음에는 값 변경이 불가능
// 변수는 상수와 다르게 다른 값 할당 가능
let sum: Int
var name: String
sum = 100 + 200
name = "안녕"
name = "이름"
만약, 상수인 값을 변경하게 된다면 상수니깐 변경하지 말라고 경고를 받아요.
모두 대괄호를 이용해서 정의할 수 있어요.
var languages = ["Swift", "Objective-C", "Python"]
var capitals = [
"한국": "서울",
"일본": "도쿄",
"중국": "베이징",
]
languages[0] // Swift
languages[1] = "Ruby"
capitals["한국"] // 서울
capitals["프랑스"] = "파리"
// 타입 명시
var languages: [String] = ["Swift", "Objective-C", "Python"]
var capitals: [String: String] = [
"한국": "서울",
"일본": "도쿄",
"중국": "베이징",
]
// 빈 배열 선언
var languages: [String] = []
var capitals: [String: String] = [:]
// ()를 쓰는 것은 생성자를 호출하는 것
var languages = [String]()
var capitals = [String: String]()
Swift의 모든 타입들은 대문자로 시작해요.
Generic Type에서만 대문자를 사용하는 다른 언어들과는 조금 다릅니다.
Boolean의 약자입니다.
다른 언어들과 동일하게 true, false를 담는 역할을 해요. 하지만 0, 1은 담지 못합니다.
Swift에서는 딱 true, false만 사용할 수 있으니 그 점 주의해서 사용하세요.
var isRed: Bool = true
isRed = false
Integer의 약자입니다.
정수 타입의 데이터를 모두 담을 수 있으나, 범위를 벗어나는 숫자를 대입하면 컴파일 오류가 발생해요.
기본적으로 64비트 정수형 데이터 타입을 나타내고, 8, 16, 32, 64비트 형태를 가지고 있어요.
Integer와 비슷하게 생겼으니 같이 소개할게요.
이 친구도 Integer입니다. 하지만 Unsigned Integer 입니다.
Unsigned Integer?
Unsigned 뜻 그대로, 부호가 없다는 말이에요. 부호가 없기 때문에 - 부호는 신경쓰지 않습니다.
정수 타입의 데이터를 모두 담을 수 있는 Int와는 다르게, 0를 포함한 양의 정수 타입의 데이터만 모두 담을 수 있습니다.
기본적으로 64비트 양의 정수 타입의 데이터를 나타내고, 8, 16, 32, 64비트 형태를 가지고 있어요.
var pressCount: Int = 0
let unsignedInteger: UInt = 50
Int랑 UInt는 다른 타입입니다. 그래서 Int를 UInt에 대입하면 컴파일 에러가 발생해요.
Int는 +, - 부호를 포함한 정수를 뜻하고 이 중 - 부호를 포함하지 않고 0을 포함한 양의 정수를 UInt로 표현해요.
Int가 -로 나타내는 부분만큼을 양의 정수로 가지고 있기 때문에 UInt는 Int보다 더 많은 양의 정수를 가지게 됩니다.
그럼 - 없이 양의 정수만 사용한다고 하면 UInt를 써야겠네요?
절대 아닙니다.
플랫폼의 기본 워드 크기와 같은 크기의 부호없는 정수 타입이 필요할때만 UInt를 사용합니다.
그렇지 않은 경우에, 저장할 값이 음수가 아닌(nonnegative) 경우에도 Int를 사용(preferred)합니다.
정수 값에 대해 Int를 일관성 있게 사용하는 것은 Type Safety and Type Inference에서 설명된것처럼,
코드의 운용성(interoperability)을 도와주며, 다른 숫자 타입으로 변환할 필요가 없고, 정수 타입 추론을 일치시킵니다.
UInt는 언제 써요?
외부 소스로부터 명시적인 크기의 데이터 또는 성능상, 메모리 사용, 또는 최적화가 필요한 경우, 특별히 다르게 처리해야할 필요가 있는 경우에만 다른 정수 타입을 사용합니다.
32비트 실수 데이터입니다.
Float는 Double를 설명하고 나서 더 자세하게 소개하겠습니다.
64비트 실수 데이터입니다.
Float와 Double 모두 부동소수점을 사용하는 실수형입니다. 소수점 자리가 있는 수이지요.
Double과 Float의 차이는 각각의 타입이 담을 수 있는 비트가 다르다는 것 입니다.
Double이 더 많은 수를 담을 수 있고 최소 15자리의 십진수를 표현 가능해요. 반면에 Float는 6자리 숫자까지 표현 가능합니다.
아마 다른 언어를 사용해본 경험이 있으신 분들은 Float를 Double에 담으려고 한다거나, Double를 Float에 담으려고 하는 일이 가능하다고 생각이 들텐데요.
아쉽게도 Swift에서는 서로 담을 수 없습니다. 위에 있는 Int와 UInt가 다른 것처럼 Float와 Double도 다릅니다.
혹시 실수 데이터를 저장해야하는 일이 생겼다면, Float와 Double중에 어떤 걸 선택해야 할까요?
둘 중 하나를 선택해서 써야하는데 뭘 써야할 지 모르겠다면 Double 사용을 권장합니다. 더 많이 들어가니깐요!
그리고 Swift는 항상 부동 소수점 숫자를 추론할 때 Float 대신에 Double를 선택합니다.
let floatValue: Float = 123456.1
let doubleValue: Double = 1234567890.1
문자를 담을 수 있는 타입입니다.
유니코드로 된 데이터라면 모두 담기 가능해요. 하지만 문자열은 대입 불가입니다.
유니코드 문자를 스위프트에서 사용하기 때문에 영어는 물론, 유니코드에서 지원하는 모든 언어 및 특수기호 등을 사용 가능해요!
let alphabet: Character = "A"
let k-alphabet: Character = "ㄱ"
문자열을 담는 타입입니다.
문자열끼리 + 도 가능해요. 하지만 문자형(Character)과는 결합 불가입니다.
""" """를 사용하면 여러 줄 넣기도 가능해요. 하지만 줄바꿈을 해주지 않으면 인식을 못해 에러가 발생해요.
var name = "Yoonah"
var age = "hi"
let me = name + " " + age
print(me) // Yoonah hi
let longString = """
문자열을
길게 사용가능
합니다.
길게
길게
사용할 수 있어요.
"""
typealias
는 기존 타입에 다른 이름을 정의해줘요.
기존 타입을 문맥상 더 적절한 이름으로 참고하고자 할 때 유용해요.
새로 지정한 별명은 원래 이름을 사용할 수 있는 곳 어디서든 사용할 수 있습니다.
typealias는 새로운 타입을 생성하는 것이 아닙니다!
단순히 별칭을 사용했을 때 실제 타입을 참조, 대신해서 사용하는 것을 허용해주는 것입니다!
typealias Pair = (Int, Int)
var pair: Pair = (1, 2)
기본 데이터를 사용해서 typealias를 만드는 경우는 보지 못했고, 제네릭 타입을 지정하거나 프로토콜 내에서 별칭을 사용할 때 쓰는 경우는 많이 봤던 거 같아요.
이런 경우들은 나중에 한 번 다뤄보도록 하겠습니다.