[iOS] 프로그래밍 실무 복습 #2 - 데이터 타입(자료형), 상수(let), 변수(var), 튜플(Tuple), 옵셔널(optional), 연산자(operator), 제어문(Control Flow), 함수

2025. 3. 7. 16:16iOS프로그래밍실무

더보기

이 글은 한성현 교수님의 ‘iOS 프로그램 실무’ 강의를 수강한 후, 복습을 위해 작성된 글입니다.

주로 실습 위주의 내용을 다루고 있으며, 실습 과정에서 사용된 Swift 문법에 대한 자세한 설명은 아래 글에서 정리해 두었으니 참고해 주시길 바랍니다.


 

[Swift] 문법 정리 - 데이터 타입(자료형), 상수(let), 변수(var), 튜플(Tuple)

https://youtu.be/R8OWOgCNt4M?si=bldau6gYEZ3seGj2위 영상을 보고 정리한 글입니다. (4:39 ~ 6:47) # 데이터 타입 (자료형, data type) 1. mynumber 라는 이름의 변수를 생성 후 숫자 10을 할당var mynunber = 10 2. 아래와 같

wse46.tistory.com

 

🔷 데이터 타입(자료형, data type)

 

Swift는 정적 타입 언어로, 변수를 선언할 때 자료형(데이터 타입)이 정해짐.

타입을 명시적으로 지정할 수도 있고, 타입 추론(Type Inference) 을 통해 자동으로 결정할 수도 있음.


1. 변수 선언과 타입 명시

 

변수를 선언하고 정수형(Int) 타입을 명시한 후, 값을 할당하는 예제

var x : Int
x = 10

 

하지만 초깃값이 있다면 타입을 명시할 필요 없음

Swift 컴파일러가 자동으로 Int 타입을 추론함.

var x = 10 // 타입 추론: Int

 

⚠️ = 연산자 양쪽에는 일관된 공백을 사용해야 함

var x= 10 // ❌ 오류 발생
var x = 10 // ✅ 올바른 문법

error '=' must have consistent whitespace on both sides


2. 변수의 데이터 타입 확인

 

어떤 자료형인지 알고싶다면  type(of:) 을 사용하면 됨.

var x = 10
print(type(of: x)) // 출력: Int

3. 메모리 크기 확인

 

특정 타입이 차지하는 메모리 크기는 MemoryLayout<T>을 사용하여 확인할 수 있음.

print(MemoryLayout<Int>.size) // 플랫폼에 따라 4 또는 8 (바이트 단위)
print(MemoryLayout<Int>.stride) // 8 (메모리 정렬 고려한 크기)
print(MemoryLayout<Int>.alignment) // 8 (정렬 기준)

 


4. 정수형 데이터 타입 (Int)

var x = 10
print(x) // 10
print("x") // "x" (변수명이 아닌 문자열 출력)
print("\(x)") // 10 (문자열 내에서 변수 값 출력)
print("값은 \(x)입니다.") // "값은 10입니다."

문자열 내에서 변수를 출력할 때는 "\(변수명)" 형식을 사용


2. 부동 소수점 데이터 타입 (Double, Float)

 

Swift에서 소수점을 포함한 숫자는 기본적으로 Double(64비트) 타입으로 처리됨.

만약 Float(32비트)을 사용하려면 명시적으로 지정해야 함.

var a = 3.14 // 기본적으로 Double 타입
var b: Float = 3.14 // Float을 사용하려면 자료형을 명시해야 함

3. 문자 (Character) vs 문자열 (String)

 

🔶 문자(Character)

 

Character 타입은 유니코드 문자 하나를 저장하는 타입으로

초깃값을 할당할 때 큰따옴표(” “)를 사용하며, 작은따옴표(’ ’)는 지원되지 않음.

var myChar1: Character // 선언만 함
var myChar2: Character = ":" // 문장 부호 저장
var myChar3: Character = "X" // 문자 저장

 

⚠️ 타입을 생략하면 기본적으로 String으로 인식됨

var myChar3 = "X" // 타입을 명시하지 않으면 String으로 인식됨
print(type(of: myChar3)) // 출력: String

 

🔶 유니코드 문자(Unicode Scalar)

 

유니코드 값을 사용하여 Character 타입에 특정 문자를 할당할 수도 있음.

var myChar4: Character = "\u{0058}" // 'X' 저장
print(myChar4) // 출력: X

myChar4 = "\u{263B}" // ☻ (스마일 심볼) 저장
print(myChar4) // 출력: ☻

 

📌 정리

더보기

타입 명시와 타입 추론: var x: Int = 10 vs var x = 10 (타입 추론)

데이터 타입 확인: type(of: x)

메모리 크기 확인: MemoryLayout<T>.size

정수형 데이터 타입: Int (플랫폼에 따라 크기 다름)

부동소수점 타입: Double(기본), Float(명시적으로 사용)

문자(Character)와 문자열(String) 구분

유니코드 값을 사용하여 문자 저장 가능 (\u{XXXX})


🔷 변수(var) vs 상수(let)

 

1. 변수(var)

변수는 var 키워드를 사용하여 선언하며, 값을 변경할 수 있음.

var myVariable = 10 // Int 타입 (타입 추론)
var x = 0.0, y = 0.0, z = 0.0 // Double 타입으로 자동 인식

 

2. 상수(let)

상수는 let 키워드를 사용하여 선언하며, 한 번 값을 할당하면 변경할 수 없음.

코드에서 반복적으로 사용되는 값을 상수로 선언하면 코드 가독성이 좋아지고, 실수로 값을 변경하는 것을 방지할 수 있음.

let maximumNumber = 10
let π = 3.14159
let 🐶🐮 = "dogcow" // Unicode 문자(이모티콘, 한글, 중국어 등)도 사용 가능

 

⚠️ 상수는 값 변경 불가

let maxUserCount = 20
maxUserCount = 30 // 오류 발생: 'maxUserCount' is a 'let' constant

 

💡 Swift는 효율성과 성능을 위해 var보다는 let 사용을 권장


3. 타입 어노테이션과 타입 추론

 

Swift는 타입 안전(type safe) 을 보장하는 언어로, 변수나 상수에 다른 타입의 값을 저장할 수 없음.

변수와 상수의 타입을 명확히 하는 방법은 타입 어노테이션(type annotation)과 타입 추론(type inference) 두 가지가 있음.

 

✔ 타입 어노테이션

 

변수나 상수의 타입을 명시적으로 선언하는 방법

var userCount: Int = 10 // Int 타입 명시
let bookTitle: String

 

✔ 타입 추론

타입을 명시하지 않아도 Swift가 할당된 값에 따라 자동으로 타입을 추론

var signalStrength = 2.231 // Double 타입으로 추론됨
let companyName = "My Company" // String 타입으로 추론됨

4. 상수의 값 할당

 

타입 어노테이션을 사용하면, 선언 후 나중에 값을 할당할 수도 있음.

단, 한 번 값이 할당되면 변경할 수 없음.

let bookTitle: String // 선언만 하고 값 할당 X
var book = true

if book {
    bookTitle = "iOS"
} else {
    bookTitle = "Android"
}

print(bookTitle) // "iOS" 출력

 

⚠️ 이미 값이 할당된 상수에 다시 값을 할당하면 오류 발생

Syntax error: cannot assign to value: 'bookTitle' is a 'let' constant


🔷 튜플(Tuple)

 

튜플은 여러 개의 값을 하나의 개체로 묶는 기능으로, Swift에서 강력하게 활용될 수 있음.

특히, 서로 다른 타입의 값을 한 번에 저장할 수 있다는 점이 특징임.


1. 튜플의 기본 개념

 

튜플은 소괄호 ( ) 안에 쉼표(,)로 구분된 값들의 집합

let myTuple = (10, 12.1, "Hi")

 

위의 myTuple(Int, Double, String) 타입의 튜플

이처럼 튜플은 서로 다른 타입을 포함할 수 있으며, 저장된 값들이 반드시 동일한 타입일 필요는 없음.

 

튜플과 배열의 차이점:

배열(Array): 같은 타입의 데이터를 여러 개 저장

튜플(Tuple): 서로 다른 타입의 데이터를 한 개체로 묶음

let oddNumbers = [1, 3, 5, 7, 9] // Swift Array (모든 요소가 Int)

2. 튜플의 요소 접근 방법

 

✔ 인덱스를 사용하여 값 접근

 

튜플의 값은 인덱스를 사용하여 접근할 수 있음.

 

⚠️ 인덱스는 0부터 시작

let myTuple = (10, 12.1, "Hi")

var myString = myTuple.2
print(myString) // "Hi"
print(type(of: myTuple)) // (Int, Double, String)

💬 myTuple의 자료형은 (Int, Double, String)


3. 튜플의 값 추출과 무시하기

 

튜플의 모든 값을 개별 변수에 할당할 수 있음.

let myTuple = (10, 12.1, "Hi")
let (myInt, myFloat, myString) = myTuple

print(myInt)   // 10
print(myFloat) // 12.1
print(myString) // "Hi"

 

특정 값이 필요 없을 경우 밑줄 _ 을 사용하여 무시할 수도 있음.

var (myInt, _, myString) = myTuple // 가운데 값(12.1)은 무시됨

print(myInt)    // 10
print(myString) // "Hi"

4. 튜플에 이름 지정하기

 

튜플을 만들 때, 각 요소에 이름을 부여할 수도 있음.

이렇게 하면 가독성이 좋아지고, 인덱스 대신 이름을 사용하여 접근할 수 있음.

let myTuple = (count: 10, length: 12.1, message: "Hi")

print(myTuple.message) // "Hi"
print(myTuple.2)       // "Hi"
print(type(of: myTuple)) // (count: Int, length: Double, message: String)

💡 myTuple.messagemyTuple.2는 동일한 값을 가리킴.

💬 myTuple의 자료형은 (count: Int, length: Double, message: String)


5. 함수에서 여러 값 반환하기

 

튜플은 함수에서 여러 개의 값을 반환할 때 매우 유용함.

func getUserInfo() -> (String, Int) {
    return ("Alice", 25)
}

let user = getUserInfo()
print("이름: \(user.0), 나이: \(user.1)") // "이름: Alice, 나이: 25"

 

이름을 지정하면 더 직관적인 코드가 됨.

func getUserInfo() -> (name: String, age: Int) {
    return ("Alice", 25)
}

let user = getUserInfo()
print("이름: \(user.name), 나이: \(user.age)") // "이름: Alice, 나이: 25"

6. typealias Void = ()

 

Swift에서 Void 빈 튜플 ()을 의미함.

 

✔ 반환값이 없는 함수

 

함수의 반환값이 없는 경우, 명시적으로 Void 또는 ()을 지정할 수 있음.

func logMessage(_ message: String) -> Void {
    print("Message: \(message)")
}

 

또는 Void를 생략할 수도 있음.

func logMessage(_ message: String) {
    print("Message: \(message)")
}

 

✔ 함수 타입에서 Void는 생략 불가

 

클로저나 함수 타입을 사용할 때는 Void를 명확하게 적어야 함.

let logger: (String) -> Void = logMessage
logger("Hello") // "Message: Hello"

 

📌 정리

더보기

✅ 튜플은 서로 다른 타입의 값을 하나의 개체로 묶을 수 있음

✅ 값에 인덱스로 접근하거나, 변수/상수에 할당하여 분해 가능

 불필요한 값은 _로 무시 가능

 각 요소에 이름을 부여하여 가독성을 높일 수 있음

 함수에서 여러 개의 값을 반환하는 데 유용

 Void는 빈 튜플 ()이며, 반환값이 없는 함수의 반환 타입으로 사용


2024.09.15 - [iOS프로그래밍기초(Smile Han)/문법 정리] - [Swift] 문법 정리 - optional, as, nil, Any, AnyObject

 

[Swift] 문법 정리 - optional, as, nil, Any, AnyObject

https://youtu.be/R8OWOgCNt4M?si=bldau6gYEZ3seGj2위 영상을 보고 정리한 글입니다 (6:48 ~ 11:40)   # 옵셔널 타입 (optional type)옵셔널 데이터 타입은 다른 프로그래밍 언어에는 없는 새로운 개념값을 반환할 때

wse46.tistory.com

 

🔷 옵셔널(Optional)

 

값이 있을 수도 있고 없을 수도 있는 상태를 안전하게 처리할 수 있게 해주는 Swift의 중요한 기능


1. 옵셔널 타입 기본 개념

 

🔶 Int vs Optional Int

 

Int정수형 데이터 타입으로, 값을 반드시 가지고 있어야 함.

var x: Int = 10 // x는 반드시 10이어야 함.

 

Int?옵셔널 정수형으로, 정수 값을 저장할 수도 있고, nil을 저장할 수도 있음.

var y: Int? = 10 // y는 10 또는 nil일 수 있음.
var z: Int! // z는 nil일 수도 있음. (Implicitly Unwrapped Optional)

 

Int?Int!의 차이는 강제 언래핑 여부

- Int?는 옵셔널이지만 nil을 안전하게 처리해야 하므로 언래핑이 필요함.
- Int!값이 반드시 있을 거라고 가정하는 옵셔널로, 값이 없을 경우 런타임 오류가 발생할 수 있음.


2. 옵셔널이란?

 

옵셔널은 값이 있을 수도 있고, 없을 수도 있는 상태

예를 들어, 사용자가 입력한 값이 Int로 변환 가능한 경우에는 값이 존재하지만, 그렇지 않으면 nil을 반환함.

let validInt = Int("100") // 값이 100으로 변환되면 Optional(100)
let invalidInt = Int("Hi") // 변환 불가능 -> nil

 

⚠️ 기본 자료형 (Int, Double, String 등)은 nil을 저장할 수 없음.

옵셔널 타입을 사용해야만 값이 없을 경우 nil을 저장할 수 있음.


3. 옵셔널 타입 선언

 

옵셔널 타입은 변수나 상수에 값이 없을 수 있음을 명시하고 처리함.

옵셔널 타입을 선언할 때 타입 뒤에 ?를 붙임.

var index: Int? // index는 Int 값 또는 nil을 가질 수 있음

 

옵셔널의 특징:

Int? : 값을 가질 수도 있고, nil을 가질 수도 있음.

Int! : 값을 반드시 가질 것이라고 가정, 값이 없으면 런타임 오류 발생.


4. 옵셔널 강제 언래핑 (Forced Unwrapping)

 

옵셔널 변수에 저장된 값을 강제로 꺼내는 방법강제 언래핑이라고 함.

강제 언래핑은 ! 연산자를 사용하여 옵셔널 변수에 담긴 값을 추출함.

var x: Int? // 옵셔널 정수형 변수 x 선언
x = 10 // x는 Optional(10)으로 래핑됨

print(x) // 출력: Optional(10)
print(x!) // 강제 언래핑: 10 출력

⚠️ 강제 언래핑은 nil 값이 있을 경우 런타임 오류가 발생.

var y: Int? = nil
print(y!) // 오류 발생: nil을 강제 언래핑 시도

 

강제 언래핑 사용 시 오류 발생 예시

var x: Int? = 10
var y: Int = 0

x = x + 2 // 오류 발생: 옵셔널 타입에서 연산 불가
y = x     // 오류 발생: 타입이 다름 (Int? -> Int)

1. x = x + 2:

x는 옵셔널 타입(Int?)이므로, 옵셔널 값에 대한 연산은 직접적으로 할 수 없습니다. 연산을 하려면 먼저 옵셔널을 언래핑해야 함.

 

2. y = x:

y는 일반 Int 타입이고, x는 옵셔널 Int? 타입입니다. 두 타입이 다르므로, y = x와 같은 직접적인 할당은 컴파일 오류가 발생함.

 

💬 오류 수정 예시

var x: Int? = 10
var y: Int = 0

x = x! + 2
y = x!

print(x) // Optional(12)
print(y) // 12

5. 옵셔널 연산자와 안전한 처리

 

옵셔널을 사용할 때 강제 언래핑 외에도 여러 가지 안전한 방법이 있음.

 

🔶 옵셔널 바인딩 (Optional Binding)

옵셔널에 값을 안전하게 할당하고 처리하는 방법입니다.

var x: Int? = 10

if let xx = x { // 옵셔널 변수 x가 값이 있으므로 언래핑 후 사용
    print(x, xx) // Optional(10) 10
} else {
    print("nil")
}
var x: Int? = 10

if let x = x { // 옵셔널 변수 x가 값이 있으므로 언래핑 후 사용
    print(x) // 10
} else {
    print("nil")
}

 

var x: Int? = 10

if let x { // 옵셔널 변수 x가 값이 있으므로 언래핑 후 사용
    print(x) // 10
} else {
    print("nil")
}

 

🔶 여러 옵셔널을 언래핑

여러 옵셔널 변수를 한번에 언래핑하는 방법은 콤마 사용

var pet1: String? = "cat"
var pet2: String? = "dog"

if let firstPet = pet1, let secondPet = pet2 {
    print(firstPet, secondPet)
} else {
    print("nil")
}

💬 과제 : 위 소스를 short form of if-let to the Optional Binding으로 변경


📌 정리

더보기

옵셔널 값이 없을 수도 있는 변수를 다룰 수 있게 해줌.

옵셔널 타입은 **?**를 사용하여 선언하고, 강제 언래핑 !를 사용함.

강제 언래핑은 안전하게 사용해야 하며, 옵셔널 바인딩이나 옵셔널 체이닝을 통해 더 안전하게 옵셔널을 처리할 수 있음.


🔷 Nil-Coalescing Operator (Nil합병연산자) ??