


class Person {
var name: String
var age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
let kim: Person = Person(name: "Kim", age: 20)
//print(kim.age) //20
let han: Person? = Person(name: "Han", age: 25)
//print(han.age) //error
print(han!.age) //옵셔널 형이기 때문에 풀어서 접근한다
print(han?.age) //Optional(25), 옵셔널 체이닝
print((han?.age)!)
if let hanAge = han?.age {
print(hanAge)
} else {
print("nil")
}
class Company {
var ceo: Person? // ceo는 있을 수도 없을 수도 있음 (옵셔널)
}
class Person {
var name: String
init(name: String) {
self.name = name
}
}
let apple = Company()
apple.ceo = Person(name: "Kim") // ceo에 Kim 할당
// ❌ 오류: ceo가 옵셔널(Person?)이라 바로 .name 접근 불가
print(apple.ceo.name)
// ✅ 방법1: if let으로 옵셔널 벗기기
// ceo가 nil이 아니면 ceo를 꺼내서 일반 변수처럼 사용
if let ceo = apple.ceo {
print(ceo.name) // Kim
}
// ✅ 방법2: 강제 언래핑 !
// "ceo 무조건 있어!" 하고 강제로 벗김
// ceo가 nil이면 💥 크래시
print(apple.ceo!.name) // Kim
// ✅ 방법3: 옵셔널 체이닝 ?.
// "ceo 있으면 .name 접근하고, nil이면 그냥 nil 반환해"
// 안전하지만 결과가 Optional로 감싸짐
print(apple.ceo?.name) // Optional("Kim")
// ✅ 방법4: 옵셔널 체이닝 + if let (가장 권장)
// ceo?.name 결과를 name에 담아서
// 값 있으면 if 실행, nil이면 else 실행
if let name = apple.ceo?.name {
print(name) // Kim (옵셔널 벗겨진 순수 String)
}
// ✅ 방법5: 옵셔널 체이닝 + ?? (nil 병합 연산자)
// ceo?.name이 nil이면 ?? 뒤의 기본값 사용
print(apple.ceo?.name ?? "CEO가 없습니다") // Kim
// apple.ceo = nil 이었다면 → "CEO가 없습니다" 출력
.앞에 !가 아닌 ?를 이용하여 옵셔널을 푸는 것을 optional chaining 옵셔널 체이닝 이라고 한다.

do-catch 구문
throws로 전파하고 do-catch로 처리
가장 일반적이고 널리 사용되는 방법으로, 에러를 명시적으로 처리할 수 있음

do {
try 오류 발생 코드
오류가 발생하지 않으면 실행할 코드
} catch 오류패턴1 {
처리 코드
} catch 오류패턴2 where 조건 {
처리 코드
} catch {
처리 코드
}
do~try~catch로 error handing해야 함
하지 않으면
Call can throw, but it is not marked with 'try' and the error is not handled"
오류가 발생

var x : [Int] = [] //빈 배열
var y = [Int]()
var z : Array<Int> = []
var a : [Int] = [1,2,3,4]
var b : Array<Int> = [1,2,3,4]
var c : Array<Double> = [1.2,2.3,3.5,4.1]
빈 배열은 append함수를 이용하여 값을 넣을 수 있다.
var number : [Int] = []
//빈 배열을 let으로 만들 수는 있지만 초기값에서 변경 불가이니 배열의 의미 없음
var odd = [Int]()
var even : Array<Int> = Array()
print(number) //[]
//print(number[0]) //오류, 빈 배열을 값을 넣은 다음에 접근
number.append(100) //let으로 선언한 불변형 배열이라 추가 불가능
//error: cannot use mutating member on immutable value: 'number' is a 'let' constant
print(number[0])
number.append(200)
print(number[0], number[1],number)
let num = [1, 2, 3, 4]
let num1 = [Int]()
print(num.first, num.last)//Optional(1) Optional(4)
print(num1.first, num1.last)//nil nil
if let f = num.first, let l = num.last {
print(f,l) //1 4
}
swift의 배열에는 빈 배열이 있을 수 있기 때문에 옵셔널 형으로 나온다.


var num = [1,5,3,2,4]
num.sort() //오름차순 정렬하여 원본 변경
print(num) //[1, 2, 3, 4, 5]
num[0...4] = [2,3,4,5,1]
num.sort(by:>) //내림차순 정렬하여 원본 변경
print(num) //[5, 4, 3, 2, 1]
num[0...4] = [2,3,4,5,1]
num.reverse() //반대로 정렬하여 원본 변경
print(num) //[1, 5, 4, 3, 2]
print(num.sorted()) //오름차순 정렬 결과를 리턴하고, 원본은 그대로, var x = num.sorted()
//[1, 2, 3, 4, 5]
print(num) //[1, 5, 4, 3, 2]
print(num.sorted(by:>)) //내림차순 정렬 결과를 리턴하고, 원본은 그대로
//[5, 4, 3, 2, 1]
print(num)//[1, 5, 4, 3, 2]