개발🧑‍💻/Swift

[Swift] 데이터 타입 (1) - 기본

* 이 글은 "스위프트 프로그래밍 (3판)" 및 야곰닷넷의 "스위프트 기초 강의"를 들으며 정리한 내용입니다.

 

1. 데이터 타입 (Data Type, 자료형)

 데이터 타입은 프로그램 내에서 다뤄지는 데이터의 종류를 뜻합니다. 스위프트의 기본 데이터 타입은 구조체를 기반으로 스위프트의 다양한 기능인 익스텐션, 제네릭 등을 사용하여 구현되어 있습니다. 스위프트의 모든 데이터 타입 이름은 첫 글자가 대문자로 시작하는 대문자 카멜케이스를 사용합니다.

 

2. Int/UInt

 정수 타입으로, Int는 +/- 부호를 포함한 정수를 나타내며 - 부호를 포함하지 않는 0을 포함한 양의 정수는 UInt로 나타냅니다. Int와 UInt 타입의 최댓값과 최솟값은 max와 min 프로퍼티를 사용하여 알 수 있습니다. Int/UInt는 8,16,32,64 비트의 형태를 가지고 있습니다. Int8, Int16, Int32, Int64, UInt8, UInt16, UInt32, UInt64 으로 저장할 수 있는 데이터의 크기에 따라 타입이 분리되어 있습니다. 시스템 아키텍처에 따라 Int와 UInt의 타입이 달라집니다. 즉, 32비트 아키텍처에서는 Int32가 Int 타입, UInt32가 UInt 타입으로 지정됩니다. 64비트 아키텍처에서는 Int64가 Int 타입, UInt64가 UInt 타입으로 지정됩니다. 

var integer : Int = -17
let unsignedInteger : UInt = 17
// UInt 에는 음수값 할당 불가

print("integer 값 : \(integer), unsignedInteger 값 : \(unsignedInteger)")
print("Int 최댓값 : \(Int.max), UInt 최댓값 : \(UInt.max)")
print("Int 최솟값 : \(Int.min), UInt 최솟값 : \(UInt.min)")

let largeInteger : Int64 = Int64.max
let smallUnsignedInteger : UInt8 = UInt8.max

print("Int64 최댓값 : \(Int64.max), UInt8 최댓값 : \(UInt8.max)")

let tooLarge : Int = Int.max + 1 // 오류
// Arithmetic operation '9223372036854775807 + 1' (on type 'Int') results in an overflow

let cannotBeNegative : UInt = -1 // 오류
// Negative integer '-1' overflows when stored into unsigned type 'UInt'

integer = unsignedInteger // 오류, Int와 UInt는 다른 타입이므로 아래처럼 캐스팅 해주어야 함
// Cannot assign value of type 'UInt' to type 'Int'
integer = Int(unsignedInteger)

 

각 진수에 따라 정수를 표현하는 방법도 있습니다.

 

2진수 : 접두어 0b를 사용하여 표현합니다.

8진수 : 접두어 0o를 사용하여 표현합니다.

16진수 : 접두어 0x를 사용하여 표현합니다.

 

let decimalInt : Int = 28 // 28
let binaryInt : Int = 0b11100 // 28
let octalInt : Int = 0o34 // 28
let hexadecimalInt : Int = 0x1C // 28

 

3. Bool

 Bool은 불리언 타입입니다. 불리언 타입은 참(True) / 거짓(False)의 두가지 중 하나만 값으로 가집니다.

var boolean : Bool = true
boolean.toggle() // false
// true <-> false 반전

let myNameIsJegyun : Bool = true
let isTimeUnlimited : Bool = false
print("시간은 무한합니까? : \(isTimeUnlimited)")
// 시간은 무한합니까? : false

 

4. Float과 Double

 Float 과 Double은 부동소수점을 사용하는 실수이며, 부동소수 타입이라고 합니다. (흔히 우리가 말하는 소수점 자리가 있는 수)

부동소수 타입은 정수 타입보다 훨씬 넓은 범위의 수를 표현할 수 있습니다. 스위프트에는 64비트 부동소수 표현을 하는 Double32비트 부동소수 표현을 하는 Float이 있습니다.

 

 64비트 환경에서 Double은 최소 15자리의 십진수를 표현할 수 있고, Float은 6자리의 숫자까지만 표현이 가능합니다.

(이 책에서는 무엇을 사용해야 할 지 잘 모르는 상황에서는 Double을 사용하길 권하였습니다.)

 

var floatValue : Float = 1234567890.1
// float이 수용할 수 있는 범위 초과 -> float의 수용가능한 범위까지만 남기므로 정확도가 떨어짐

let doubleValue : Double = 1234567890.1
// 반면에 doubled은 이 수를 수용할 수 있음

print("floatValue : \(floatValue), DoubleValue : \(doubleValue)")
// floatValue : 1.234568e+09, DoubleValue : 1234567890.1

floatValue = 123456.1
// float이 수용할 수 있는 수로 변경

 

4. Character

 Character는 말 그대로 '문자'를 의미합니다. 단어나 문장처럼 문자의 집합이 아닌, 단 하나의 문자를 의미합니다.

스위프트는 유니코드 9 문자를 사용하므로 영어는 물론, 유니코드에서 지원하는 모든 언어 및 특수기호를 사용할 수 있습니다. 문자를 표현하기 위해서는 값의 앞뒤에 큰따옴표를 사용하여 표현합니다.

 

let alphabetA: Character = "A"
let alphabetB: Character = "B"
let alphabetC: Character = "C"

print(alphabetA,alphabetB,alphabetC)
// A B C

 

5. String

 String은 문자열의 나열, 즉 문자열입니다. Character와 마찬가지로 String 또한 유니코드 9 을 사용할 수 있으며, 값의 앞뒤에 큰따옴표를 사용하여 표현합니다. 스위프트에서는 문자열을 손쉽게 다루기 위해 많은 메서드와 프로퍼티가 구현되어 있고, 문자열과 관련된 연산자 또한 많이 정의되어 있기 때문에 조금이나마 다루기 쉽게 지원해줍니다.

 

let name : String = "Jegyun"
// 이니셜라이저를 사용하여 빈 문자열 생성
var introduce : String = String()

// append 메서드를 사용하여 문자열을 이어붙일 수 있다.
introduce.append("My name is")

introduce += " " + name + "!"
print(introduce)
// My name is Jegyun!
print("name의 글자 수 : \(name.count)") // name의 글자 수 : 6
print("introduce가 빈 문자열인가? : \(introduce.isEmpty)") // introduce가 빈 문자열인가? : false

let unicodeScalarValue : String = "\u{2665}"
// "♥"

let hello : String = "Hello"
let jegyun : String = "Jegyun"

var greeting : String = hello + " " + jegyun + "!"

print(greeting) // Hello Jegyun!

greeting = hello

greeting += " "
greeting += jegyun
greeting += "!"

print(greeting) // Hello Jegyun!

// 연산자를 통한 문자열 비교
var isSameString : Bool = false

isSameString = hello == "Hello"
print(isSameString) // true

isSameString = hello == "hello"
print(isSameString) // false

isSameString = jegyun == "Jegyun"
print(isSameString) // true

isSameString = jegyun == "jegyun"
print(isSameString) // false

// 접두어 확인
var hasPrefix : Bool = false
hasPrefix = hello.hasPrefix("HE")
print(hasPrefix) // false

hasPrefix = hello.hasPrefix("Hello")
print(hasPrefix) // true

hasPrefix = jegyun.hasPrefix("Je")
print(hasPrefix) // true

hasPrefix = jegyun.hasPrefix("jegyun")
print(hasPrefix) // false



// 접미어 확인
var hasSuffix: Bool = false
hasSuffix = hello.hasSuffix("llo")
print(hasSuffix) // true

hasSuffix = hello.hasSuffix("LLo")
print(hasSuffix) // false

hasSuffix = jegyun.hasSuffix("gyun")
print(hasSuffix) // true

hasSuffix = jegyun.hasSuffix("jegyun")
print(hasSuffix) // false

// 메서드를 통한 대소문자 변환

var convertedString : String = ""
convertedString = hello.uppercased()
print(convertedString) // HELLO

convertedString = hello.lowercased()
print(convertedString) // hello


// 프로퍼티를 통한 빈 문자열 확인
var isEmptyString : Bool = false
isEmptyString = greeting.isEmpty
print(isEmptyString) // false

greeting = ""
isEmptyString = greeting.isEmpty
print(isEmptyString) // true

// 프로퍼티를 통한 문자열 길이 확인

print(greeting.count) // 0

greeting = "Jegyun"
print(greeting.count) // 6

// 여러 줄의 문자열 작성

greeting = """
Swift 공부
열심히 하기
!
"""

print(greeting)
/*
Swift 공부
열심히 하기
!
*/

 

5-1. 특수문자

스위프트에는 문자열 내에서 일정 기능을 하는 특수문자 (혹은 제어문자) 가 있습니다.

특수문자 설명
\n 줄바꿈
\\ 문자열 내에서 백슬래시를 표현
\" 문자열 내에서 큰따옴표를 표현
\t 탭 문자 (키보드의 탭키를 눌렀을때의 효과)
\0 문자열이 끝났음을 알리는 null 문자
print("\\n은 줄바꿈 문자입니다.") // \n은 줄바꿈 문자입니다.

print("\\은 백슬래시입니다.") // \은 백슬래시입니다.

print("\t는 탭 입니다.") //     는 탭 입니다.

print("\" 는 큰따옴표 입니다.") // " 는 큰따옴표 입니다.

print(#"이렇게 양쪽에 #을 사용하여 문자열 "내부" "에서 \특수문자\를 사용하지 않고 표현할 수 있습니다."#) // 이렇게 양쪽에 #을 사용하여 문자열 "내부" "에서 \특수문자\를 사용하지 않고 표현할 수 있습니다

 

6. Any, AnyObject와 nil

 Any는 스위프트의 모든 데이터 타입을 사용할 수 있다는 뜻입니다. 변수나 상수의 데이터 타입이 Any로 되어 있다면 그 변수 또는 상수에는 어떤 종류의 데이터 타입이던 상관없이 할당할 수 있습니다. AnyObject는 Any보다는 한정된 의미로 클래스의 인스턴스만 할당할 수 있습니다. 그러나 Any와 AnyObject는 될 수 있으면 사용하지 않는 편이 좋습니다. 타입에 엄격한 스위프트의 특성상 Any / AnyObject로 선언된 변수의 값을 가져다 쓸때, 매번 타입 확인 및 변환을 해줘야 하는 불편함이 있고 또한 예기치 못한 오류의 위험을 증가시킵니다. 타입은 최대한 명시하는 것이 좋습니다.

 

var anyVar : Any = "Dinner" // Any로 선언된 변수, 문자열
anyVar = 100 // 정수
anyVar = 77.7 // 실수 
// 이처럼 어떤 타입의 값이던 할당 할 수 있다.

 

nil은 '없음'을 나타내는 스위프트의 키워드입니다. 변수 또는 상수에 값이 들어있지 않고 비어있음을 나타내는 데 사용합니다. 변수 또는 상수에 값이 없는 경우, 즉 nil인 경우에 해당 변수 또는 상수에 접근했을 때 잘못된 메모리 접근으로 런타임 오류가 발생합니다.