[iOS 프로그래밍 기초] 3주차
[iOS 프로그래밍 기초] 3주차
스위프트에서는 문자열을 더할 때, 문자열과 다른 데이터 타입(예: 정수)을 직접 연결할 수 없다.
age는 정수(Int) 타입이고, 문자열인 name과 age를 직접 연결하려고 하면 오류가 발생한다.
해결 방법으로는 age 값을 문자열로 변환하면 된다.
var age = 10
var name = "Kim Jin"
print("나의 이름은 \(name) 나이는 \(age)") //보간법
var age = 10
var name = "Kim Jin"
print("나의 이름은 " + name + " 나이는 " + String(age)) //문자열 변환
변수 선언하는 방법
var와 let을 사용한다. 이 두 가지는 변수의 가변성(mutable, immutable)에 따라 구분된다.
var는 변경 가능한 변수(mutable variable)를 선언할 때 사용된다. 즉, 선언한 후 값을 변경할 수 있다.
var age = 25
age = 30 // 변수 값을 변경할 수 있음
2. let으로 선언
let은 변경 불가능한 상수(immutable constant)를 선언할 때 사용된다. 한 번 값을 할당하면 그 이후에는 변경할 수 없다.
let name = "Kim Jin"
// name = "Lee Sun" // 오류 발생: let으로 선언한 상수는 값을 변경할 수 없음
타입 명시
스위프트는 타입 추론을 지원하므로, 변수 선언 시 값을 할당하면 자동으로 타입을 추론한다. 하지만, 명시적으로 타입을 지정할 수도 있다.
var height: Double = 180.5 // Double 타입 명시
let isStudent: Bool = true // Bool 타입 명시
주의사항
- let으로 선언한 상수는 재할당이 불가능하다.
- var로 선언한 변수는 언제든지 값을 변경할 수 있다.
- 스위프트는 강타입 언어이므로, 선언한 변수의 타입이 고정되며, 다른 타입의 값을 대입할 수 없다.

print(Int.min) // 출력: -9223372036854775808 (64비트 기준)
print(Int.max) // 출력: 9223372036854775807 (64비트 기준)
var 와 let 의 차이



tuple

1. Python
- 파이썬에서는 튜플이 매우 흔히 사용되며, ()로 둘러싸인 값들의 집합입니다. 각 요소는 서로 다른 타입을 가질 수 있으며, 불변(immutable) 특성을 가집니다.
my_tuple = (1, "Hello", 3.14)
print(my_tuple[1]) # 출력: Hello
2. Swift
- 스위프트에서는 튜플이 함수의 여러 값을 반환하거나 간단한 데이터 구조로 사용됩니다. () 안에 여러 값을 넣어 튜플을 선언하며, 각 값은 타입이 다를 수 있습니다.
let myTuple = (10, "Kim Jin", 3.14)
print(myTuple.1) // 출력: Kim Jin
3. Kotlin
- 코틀린에서 튜플과 유사한 구조로 Pair와 Triple을 제공합니다. 또한, 더 복잡한 튜플을 표현하기 위해 다양한 데이터 클래스를 사용할 수 있습니다.
val pair = Pair(1, "Hello")
println(pair.second) // 출력: Hello
val triple = Triple(1, "Hello", 3.14)
println(triple.third) // 출력: 3.14
4. C#
- C#에서는 System.Tuple 클래스를 사용하여 튜플을 만들 수 있으며, C# 7.0 이후부터는 튜플을 더 쉽게 사용할 수 있도록 문법이 개선되었습니다.
5. F#
- F#은 튜플을 광범위하게 사용하는 함수형 프로그래밍 언어입니다. F#에서 튜플은 ()로 감싸진 값의 목록으로 표현됩니다.
let myTuple = (1, "Hello", 3.14)
printfn "%s" (snd myTuple) // 출력: Hello
6. Haskell
- Haskell에서는 튜플이 고정된 크기의 컨테이너로 사용됩니다. 튜플 내의 각 요소는 서로 다른 타입을 가질 수 있습니다.
let myTuple = (1, "Hello", 3.14)
print (fst myTuple) -- 출력: 1
7. Rust
- 러스트에서는 튜플을 사용하여 여러 값을 반환하거나 구조화된 데이터를 다룰 수 있습니다. 각 요소의 타입을 지정할 수 있습니다.
let my_tuple = (1, "Hello", 3.14);
println!("{}", my_tuple.1); // 출력: Hello
8. Scala
- 스칼라에서는 튜플을 Tuple1, Tuple2, ..., Tuple22까지 지원합니다. 각 튜플은 최대 22개의 요소를 가질 수 있습니다.
val myTuple = (1, "Hello", 3.14)
println(myTuple._2) // 출력: Hello
9. Ruby
- 루비에서는 직접적인 튜플 자료형이 없지만 배열을 사용하여 튜플처럼 동작하게 할 수 있습니다. 불변 배열로 튜플과 유사한 구조를 사용할 수 있습니다.
my_tuple = [1, "Hello", 3.14]
puts my_tuple[1] # 출력: Hello
10. Go
- Go 언어에서는 튜플이 명시적인 자료형으로는 존재하지 않지만, 함수에서 여러 값을 반환할 때 튜플과 유사하게 동작합니다.
func myFunction() (int, string) {
return 1, "Hello"
}
a, b := myFunction()
fmt.Println(b) // 출력: Hello
11. Java
- 자바에서는 기본적으로 튜플을 제공하지 않지만, Apache Commons Lang 또는 Vavr와 같은 라이브러리를 통해 튜플을 사용할 수 있습니다.
import io.vavr.Tuple;
import io.vavr.Tuple2;
Tuple2<Integer, String> myTuple = Tuple.of(1, "Hello");
System.out.println(myTuple._2); // 출력: Hello
12. Dart
- Dart에서는 직접적인 튜플 타입이 없지만, List를 사용하여 튜플과 유사한 구조를 사용할 수 있습니다.
var myTuple = [1, "Hello", 3.14];
print(myTuple[1]); // 출력: Hello
13. ML 계열 언어 (OCaml, Standard ML)
- OCaml 및 Standard ML과 같은 ML 계열 언어에서도 튜플은 흔히 사용됩니다.
let my_tuple = (1, "Hello", 3.14)
Printf.printf "%s\n" (snd my_tuple) // 출력: Hello
14. Julia
- 줄리아에서는 튜플이 고정된 길이의 자료형으로, 요소의 타입이 다를 수 있습니다.
my_tuple = (1, "Hello", 3.14)
println(my_tuple[2]) # 출력: Hello
튜플을 사용하는 주요 프로그래밍 언어는 Python, Swift, Kotlin, C#, F#, Haskell, Rust, Scala, Ruby, Go, Java, Dart와 ML 계열 언어(OCaml, SML), Julia 등입니다. 각 언어에서 튜플의 사용법과 동작은 조금씩 다르지만, 기본적으로 여러 타입의 값을 하나로 묶는 방식은 공통적입니다.
스위프트의 Tuple
여러 값을 하나의 그룹으로 묶을 수 있는 데이터 구조
튜플의 중요한 특징은 각 요소가 서로 다른 타입일 수 있다는 점
let person: (String, Int, Double) = ("Kim Jin", 30, 75.5)
//선언 및 초기화
값 접근
let person = ("Kim Jin", 30, 75.5)
print(person.0) // 출력: Kim Jin
print(person.1) // 출력: 30
print(person.2) // 출력: 75.5
이름을 사용하여 접근
let person = (name: "Kim Jin", age: 30, weight: 75.5)
print(person.name) // 출력: Kim Jin
print(person.age) // 출력: 30
print(person.weight) // 출력: 75.5
let (name, age, weight) = ("Kim Jin", 30, 75.5)
print(name) // 출력: Kim Jin
print(age) // 출력: 30


스위프트의 연산자
스위프트가 다른 언어와 다른 점!
++, -- 연산자가 없다.
== (동등 연산자) : 값이 같은지를 비교한다
=== (일치 연산자) : 참조 타입(메모리 주소를 기반으로 값을 관리하는 타입)에서 두 객체가 같은 메모리 주소를 참조하는지 비교한다
범위 연산자
기본기 : 클래스 vs 객체 vs 인스턴스
설계도인 클래스로부터 만들어진 실체를 객체라 하고 실제로 사용 중인 객체를 인스턴스라 한다.
for 문
for index in 1...5 {
print(index)
}
1
2
3
4
5
//_ 로 참조체 생략 가능
for _ in 1...5 { print("안녕")
}
for i in 1...5 { print("\(i) 안녕")
}
let names = ["A", "B", "C", "D"] for name in names {
print(name)
}
for x in 1...5 {
print(x, terminator: "@") //1@2@3@4@5@
}
- separator: 여러 값을 출력할 때, 각 값 사이에 삽입되는 문자열을 지정하는 옵션 (기본값: " ").
- terminator: 출력이 끝난 후 마지막에 추가되는 문자열을 지정하는 옵션 (기본값: "\n").
print("apple", "banana", "cherry", separator: " - ", terminator: ".")
// apple - banana - cherry.
dictionary
let numberOfLegs = ["Spider": 8, "Ant": 6, "Dog": 4] //dictionary는 key:value형식의 배열
for (animalName, legCount) in numberOfLegs {
print("\(animalName)s have \(legCount) legs")
repeat~ while 반복문
repeat...while 반복문은 코드 블록을 최소한 한 번은 실행한 후, 조건을 검사하여 반복을 계속할지 결정한다
repeat {
// 실행할 코드
} while 조건
여기서 조건이 true인 동안 반복이 계속된다. repeat...while 문은 조건을 검사하기 전에 코드 블록이 먼저 실행되므로, 조건이 처음에는 false여도 블록이 적어도 한 번은 실행된다.
var number = 1
repeat {
print(number)
number += 1
} while number <= 5
//number가 1부터 5까지의 값을 출력한다. number가 6이 되면 반복이 종료된다.
var i = 10
repeat {
i = i - 1
print(i) // 이 줄은 i의 값을 출력한다
} while i > 0
반복문에서 빠져나오기
for i in 1...10 {
if i > 5 { //중괄호는 반드시 해야합니다
break
}
print(i)
}
조건 나열
스위프트의 switch-case 문에는 눈에 보이지 않는 break 가 자동으로 들어 있다!!
switch-case 에서 where절 사용하기 (부가적으로 조건을 준다)
var temperature = 60
switch (temperature)
{
case 0...49 where temperature % 2 == 0:
print("Cold and even")
case 50...79 where temperature % 2 == 0:
print("Warm and even")
case 80...110 where temperature % 2 == 0:
print("Hot and even")
default:
print("Temperature out of range or odd") }
//Warm and even
앞에 있는 조건 뿐만 아니라 where 뒤에 있는 조건까지 만족해야 한다
문법이 좋은 것이 많다 스위프트 ♥
특정 패턴과 결합하여 조건을 추가
var numbers: [Int] = [1, 2, 3, 4, 5]
for num in numbers where num > 3 {
print(num)
}
4
5
fallthrough
- case별로 빠져 나가지 않고 아래로 계속 내려가게 하려면 fallthrough 문 사용
var value = 4
switch (value) {
case 4:
print("4")
fallthrough
case 3:
print("3")
fallthrough
case 2:
print("2")
fallthrough
default:
print("1")
}
옵셔널 (optional) ****
var x : Int = 10 //일반 자료형 int 형
print(x)
var x : Int //초기화 되기 전에 변수의 값을 사용해서 오류 발생
print(x)
var x : Int? //옵셔널 : nil 출력
print(x)
var x: Int? // Optional Int 타입의 변수 x를 선언합니다. 초기값은 nil입니다.
x = 10 // x에 10을 할당합니다. 이제 x는 Optional Int 타입으로 10을 감싸고 있습니다.
print(x, x!) // x와 x!를 출력합니다.
변수 선언 및 초기화
- x는 Optional Int 타입의 변수로 선언됩니다. 이는 Int 값을 가질 수도 있고, nil일 수도 있음을 의미합니다.
- 초기 상태에서는 x는 nil입니다.
변수에 값 할당
- x에 10을 할당합니다. 여기서 10은 Optional로 감싸지며, x는 이제 Optional(10)이 됩니다.
값 출력
- x는 Optional(10)이므로 출력 시 Optional(10)으로 표시됩니다.
- x!는 강제 언래핑(Force Unwrapping)을 의미합니다. ! 연산자를 사용하면 Optional 안의 값을 직접 꺼낼 수 있습니다. 만약 x가 nil이라면 런타임 에러가 발생하지만, 여기서는 x가 10을 가지므로 x!는 10을 반환합니다.
print(x, x!) 의 값은 Optional(10) 10
- Optional(10)은 x의 Optional 타입을 나타내며,
- 10은 강제 언래핑된 값을 나타냅니다.
강제 언래핑을 사용할 때는 반드시 Optional이 nil이 아닐 때만 사용해야 하며, 그렇지 않으면 프로그램이 크래시할 수 있습니다.
값이 없다는 것을 저장하려면 반드시 옵셔널 변수를 선언해야 한다.
x = Optional(10) 이기 때문에 x+2 를 하려면 x를 ! 로 풀어주고 해야 된다
느낌표 사용 : 강제 언래핑 (forced unwrapping)
옵셔널은 연산이 안되기 때문에 꼭 언래핑을 해주어야 한다
x 가 nil 일 때 강제 언래핑을 할 수 없기 때문에 if 문을 사용하여 x 가 nil 인지 아닌지 판별하면 오류를 방지할 수 있다.
주의할 점은 if x!=nil 이라고 사용하면 안 된다. 해당 코드는 x의 값을 풀어서 nil 을 넣으라는 뜻이 된다. 따라서 != 앞뒤에 최소 한칸이상 공백을 두어야 한다.
스위프트 문법 중에 가장 많이 사용한다. -> 옵셔널 바인딩
if let과 if var는 스위프트에서 옵셔널 바인딩을 통해 값을 안전하게 추출하고 사용하는 방법
- if let: 옵셔널이 nil이 아닐 때 상수로 값을 바인딩하여 안전하게 사용한다.
- if var: 옵셔널이 nil이 아닐 때 변수로 값을 바인딩하여 사용할 수 있으며, 값을 수정할 수 있다.
가장 최근에 사용하는 옵셔널 바인딩 문법
Swift 5.7 부터 바뀌었다.
느낌표로 풀게 되면 강제 언래핑 방식으로 앱이 죽을 수도 있다. 옵셔널 바인딩을 사용하여 안전하게 풀도록 하자.
여러 옵셔널 값을 동시에 언래핑하는 방법
3가지 방법을 알고 있으면 좋다
x나 y 중 하나라도 nil 이면 nil 이 나온다
옵셔널 바인딩이라는 것은 ! 로 푸는 것보다 좋은 방법이며 3가지 방법이 있다
여러 개를 동시에 풀 때는 콤마를 쓰고 let을 계속 붙여 주면 된다
옵셔널 선언 방식은 일반적으로 물음표로 선언한다
옵셔널로 선언한 값은 연산이 불가능하지만 느낌표로 선언하면 일반형과 같이 결합해서 연산을 할 때 자동으로 일반형으로 풀려서 연산이 가능하게 된다.
var x : Int?
var y : Int!
x = 10
//x = x+2
y = 20
y = y+2
print(x,y) //Optional(10) Optional(22)
y 의 값이 증가한 것을 볼 수 있다
! (강제 추출, Force Unwraping)
옵셔널 값이 확실히 존재한다고 생각될 때 강제로 값을 꺼낼 수 있다
? (옵셔널 바인딩, Optional Binding)
안전하게 옵셔널 값을 꺼내는 방식이다
값이 존재하는지 확인하고 값이 있다면 사용할 수 있다
값이 없을 때의 상황에서 에러핸들링을 위해 사용한다고 보면 된다.
nil병합연산자 ??
: 옵셔널을 푸는 방법 중에 많이 사용한다 (nil 이면 ?? 다음 값으로 할당되고 nil 이 아니면 언래핑된 값이 나온다)
시험 문제로 잘 나온다 (스위프트는 옵셔널을 푸는 것이 굉장히 중요하다)