μλ νμΈμ μ΄λ²μλ Swift κΈ°λ³Έ κ°λ μ 리μ λ λ²μ§Έ ννΈλ‘, λΆμΈ, νν, μ΅μ λ, μλ¬ μ²λ¦¬ λ± μ€μν κ°λ λ€μ μμλ³΄κ² μ΅λλ€.
π λΆμΈ (Booleans)
Swiftλ μ°Έκ³Ό κ±°μ§μ νννκΈ° μν Bool νμ μ μ 곡ν©λλ€:
let orangesAreOrange = true
let turnipsAreDelicious = false
// 쑰건문μμ μ¬μ©
if turnipsAreDelicious {
print("Mmm, tasty turnips!")
} else {
print("Eww, turnips are horrible.")
}
// "Eww, turnips are horrible." μΆλ ₯
Bool: μ°Έ(true) λλ κ±°μ§(false) κ°λ§ κ°μ§ μ μλ λ Όλ¦¬ νμ μ λλ€.
Swiftλ νμ μμ μ±μ μν΄ λΆμΈμ΄ μλ κ°μ΄ Boolλ‘ λ체λλ κ²μ λ°©μ§ν©λλ€:
let i = 1
if i == 1 {
// μ¬λ°λ₯Έ μ¬μ©: λΉκ΅ κ²°κ³Όλ Bool νμ
}
// λ€μ μ½λλ μ»΄νμΌ μλ¬ λ°μ
// if i { ... } // μλͺ»λ μ¬μ©: iλ Boolμ΄ μλ
π νν (Tuples)
ννμ μ¬λ¬ κ°μ νλμ λ³΅ν© κ°μΌλ‘ κ·Έλ£Ήνν©λλ€:
// HTTP μν μ½λλ₯Ό λνλ΄λ νν
let http404Error = (404, "Not Found")
// νμ
μ (Int, String)
// νν λΆν΄(decompose)νκΈ°
let (statusCode, statusMessage) = http404Error
print("μν μ½λ: \(statusCode)") // "μν μ½λ: 404" μΆλ ₯
print("μν λ©μμ§: \(statusMessage)") // "μν λ©μμ§: Not Found" μΆλ ₯
// μΌλΆ κ°λ§ νμν λ
let (justTheStatusCode, _) = http404Error
// μΈλ±μ€λ‘ μ κ·Ό
print("μν μ½λ: \(http404Error.0)") // "μν μ½λ: 404" μΆλ ₯
// μ΄λ¦μ΄ μλ νν μμ
let http200Status = (statusCode: 200, description: "OK")
print("μν μ½λ: \(http200Status.statusCode)") // "μν μ½λ: 200" μΆλ ₯
νν(Tuple): μ¬λ¬ νμ μ κ°μ νλλ‘ λ¬Άμ λ³΅ν© νμ μΌλ‘, ν¨μμμ μ¬λ¬ κ°μ λ°νν λ μ μ©ν©λλ€.
π μ΅μ λ (Optionals)
μ΅μ λμ κ°μ΄ μμ μ μλ μν©μ μμ νκ² μ²λ¦¬νκΈ° μν Swiftμ ν΅μ¬ κΈ°λ₯μ λλ€:
let possibleNumber = "123"
let convertedNumber = Int(possibleNumber)
// convertedNumberλ Int? νμ
(μ΅μ
λ Int)
μ΅μ λ(Optional): κ°μ΄ μκ±°λ μμ μ μλ μν©μ νννλ νμ μΌλ‘, νμ λ€μ λ¬Όμν(?)λ₯Ό λΆμ¬ ννν©λλ€.
nil
nilμ κ°μ΄ μμμ λνλ΄λ νΉμν κ°μ λλ€:
var serverResponseCode: Int? = 404
serverResponseCode = nil // κ° μμμΌλ‘ μ€μ
// μ΄κΈ°κ° μμ΄ μ μΈλ μ΅μ
λμ μλμΌλ‘ nil
var surveyAnswer: String? // nilλ‘ μ΄κΈ°νλ¨
nil: κ°μ΄ μμμ λνλ΄λ Swiftμ νΉμ κ°μ λλ€. μ΅μ λ νμ λ§ nilμ κ°μ§ μ μμ΅λλ€.
μ΅μ λ λ°μΈλ© (Optional Binding)
μ΅μ λμ κ°μ΄ μλμ§ νμΈνκ³ μλ€λ©΄ ν΄λΉ κ°μ μμ λ³μλ μμλ‘ μ¬μ©ν μ μκ² ν©λλ€:
if let actualNumber = Int(possibleNumber) {
print("λ¬Έμμ΄ \"\(possibleNumber)\"μ μ μκ° \(actualNumber)μ
λλ€.")
} else {
print("λ¬Έμμ΄ \"\(possibleNumber)\"μ μ μλ‘ λ³νν μ μμ΅λλ€.")
}
// "λ¬Έμμ΄ "123"μ μ μκ° 123μ
λλ€." μΆλ ₯
// λ μ§§μ ννμ μ΅μ
λ λ°μΈλ© (Swift 5.7+)
let myNumber: Int? = Int(possibleNumber)
if let myNumber {
print("μ«μλ \(myNumber)μ
λλ€.")
}
// "μ«μλ 123μ
λλ€." μΆλ ₯
// μ¬λ¬ μ΅μ
λ λ°μΈλ© ν¨κ» μ¬μ©
if let firstNumber = Int("4"), let secondNumber = Int("42"), firstNumber < secondNumber {
print("\(firstNumber) < \(secondNumber)")
}
// "4 < 42" μΆλ ₯
μ΅μ λ λ°μΈλ©: μ΅μ λμ κ°μ΄ μλμ§ νμΈνκ³ , μλ€λ©΄ κ·Έ κ°μ μμ μμλ λ³μλ‘ μΆμΆνλ λ°©λ²μ λλ€.
λμ²΄κ° μ 곡 (Nil-Coalescing Operator)
nil-κ²°ν© μ°μ°μ(??)λ₯Ό μ¬μ©νμ¬ μ΅μ λμ΄ nilμΌ κ²½μ° κΈ°λ³Έκ°μ μ 곡ν μ μμ΅λλ€:
let name: String? = nil
let greeting = "μλ
νμΈμ, " + (name ?? "μΉκ΅¬") + "!"
print(greeting)
// "μλ
νμΈμ, μΉκ΅¬!" μΆλ ₯
nil-κ²°ν© μ°μ°μ(??): μ΅μ λμ΄ nilμ΄λ©΄ κΈ°λ³Έκ°μ μ 곡νλ μ°μ°μμ λλ€.
κ°μ μΈλν (Force Unwrapping)
μ΅μ λμ κ°μ΄ μλ€κ³ νμ ν λ λλν(!)λ₯Ό μ¬μ©νμ¬ κ°μ λ‘ κ°μ μΆμΆν μ μμ΅λλ€:
let possibleNumber = "123"
let convertedNumber = Int(possibleNumber)
// κ°μ μΈλν - μ΅μ
λμ κ°μ΄ μμΌλ©΄ λ°νμ μλ¬ λ°μ
let number = convertedNumber!
κ°μ μΈλν: μ΅μ λμμ κ°μ κ°μ λ‘ μΆμΆνλ λ°©λ²μΌλ‘, μ΅μ λμ΄ nilμ΄λ©΄ λ°νμ μλ¬κ° λ°μν©λλ€.
μμμ μΌλ‘ μΈλνλ μ΅μ λ (Implicitly Unwrapped Optionals)
μμμ μΌλ‘ μΈλνλ μ΅μ λμ μ²μ μ μλ ν νμ κ°μ΄ μλ€κ³ κ°μ ν μ μμ λ μ μ©ν©λλ€:
let possibleString: String? = "μ΅μ
λ λ¬Έμμ΄μ
λλ€."
let forcedString: String = possibleString! // λͺ
μμ μΈλν νμ
let assumedString: String! = "μμμ μΌλ‘ μΈλνλ μ΅μ
λ λ¬Έμμ΄μ
λλ€."
let implicitString: String = assumedString // μλμΌλ‘ μΈλνλ¨
μμμ μΌλ‘ μΈλνλ μ΅μ λ: νμ λ€μ λλν(!)λ₯Ό λΆμ¬ μ μΈνλ©°, μ κ·Όν λλ§λ€ μλμΌλ‘ μΈλνλ©λλ€.
π μλ¬ μ²λ¦¬ (Error Handling)
Swiftλ νλ‘κ·Έλ¨ μ€ν μ€ λ°μν μ μλ μλ¬λ₯Ό μ²λ¦¬νκΈ° μν λ©μ»€λμ¦μ μ 곡ν©λλ€:
// μλ¬ μ μ
enum PrinterError: Error {
case outOfPaper
case noToner
case onFire
}
// μλ¬λ₯Ό λ°μμν¬ μ μλ ν¨μ
func send(job: Int, toPrinter printerName: String) throws -> String {
if printerName == "Never Has Toner" {
throw PrinterError.noToner
}
return "μμ
μ΄ μ μ‘λμμ΅λλ€."
}
// μλ¬ μ²λ¦¬
do {
let printerResponse = try send(job: 1040, toPrinter: "Bi Sheng")
print(printerResponse)
} catch {
print(error)
}
// "μμ
μ΄ μ μ‘λμμ΅λλ€." μΆλ ₯
// μ¬λ¬ catch λΈλ‘μΌλ‘ λ€μν μλ¬ μ²λ¦¬
do {
let printerResponse = try send(job: 1440, toPrinter: "Never Has Toner")
print(printerResponse)
} catch PrinterError.onFire {
print("νλ¦°ν°κ° λΆνκ³ μμ΅λλ€!")
} catch let printerError as PrinterError {
print("νλ¦°ν° μλ¬: \(printerError).")
} catch {
print("μλ¬: \(error)")
}
// "νλ¦°ν° μλ¬: noToner." μΆλ ₯
// try?λ₯Ό μ¬μ©νμ¬ μ΅μ
λ κ²°κ³Ό λ°ν
let printerSuccess = try? send(job: 1884, toPrinter: "Mergenthaler")
// μ±κ³΅ μ String?, μ€ν¨ μ nil
Error νλ‘ν μ½: Swiftμμ μλ¬ νμ μ Error νλ‘ν μ½μ μ€μν΄μΌ ν©λλ€.
throws: ν¨μκ° μλ¬λ₯Ό λ°μμν¬ μ μμμ λνλ΄λ ν€μλμ λλ€.
throw: μλ¬λ₯Ό λ°μμν€λ ν€μλμ λλ€.
try: μλ¬λ₯Ό λ°μμν¬ μ μλ ν¨μ νΈμΆ μ μ¬μ©νλ ν€μλμ λλ€.
do-catch: μλ¬λ₯Ό ν¬μ°©νκ³ μ²λ¦¬νλ ꡬ문μ λλ€.
π μμ€κ³Ό μ μ 쑰건 (Assertions and Preconditions)
λ°νμμ 쑰건μ νμΈνμ¬ μ½λκ° μ¬λ°λ₯΄κ² μ€νλλλ‘ λ³΄μ₯νλ λ°©λ²μ λλ€:
μμ€ (Assertions)
μμ€μ λλ²κ·Έ λΉλμμλ§ νμΈλλ©°, μ‘°κ±΄μ΄ falseλ©΄ μ±μ΄ μ’ λ£λ©λλ€:
let age = -3
assert(age >= 0, "λμ΄λ μμκ° λ μ μμ΅λλ€.")
// μ΄ μμ€μ μ€ν¨νλ©°, μ±μ΄ μ’
λ£λ©λλ€.
// λ©μμ§ μμ΄ μ¬μ©
assert(age >= 0)
// μ΄λ―Έ μ‘°κ±΄μ΄ μ²΄ν¬λ κ²½μ°
if age > 10 {
print("λ‘€λ¬μ½μ€ν°λ κ΄λμ°¨λ₯Ό ν μ μμ΅λλ€.")
} else if age >= 0 {
print("κ΄λμ°¨λ₯Ό ν μ μμ΅λλ€.")
} else {
assertionFailure("λμ΄λ μμκ° λ μ μμ΅λλ€.")
}
assert: λλ²κ·Έ λΉλμμ 쑰건μ νμΈνκ³ , μ‘°κ±΄μ΄ falseλ©΄ μ±μ μ’ λ£νλ ν¨μμ λλ€.
assertionFailure: 쑰건 νμΈ μμ΄ λ°λ‘ μ±μ μ’ λ£νλ ν¨μμ λλ€.
μ μ 쑰건 (Preconditions)
μ μ 쑰건μ λλ²κ·Έμ νλ‘λμ λΉλ λͺ¨λμμ νμΈλ©λλ€:
// μΈλ±μ€κ° λ°°μ΄ λ²μ λ΄μ μλμ§ νμΈ
precondition(index > 0, "μΈλ±μ€λ 0λ³΄λ€ μ»€μΌ ν©λλ€.")
// ꡬνλμ§ μμ κΈ°λ₯μ μ¬μ©
func fetchData() -> [String] {
if useMockData {
return ["ν
μ€νΈ λ°μ΄ν°"]
} else {
preconditionFailure("μμ§ κ΅¬νλμ§ μμμ΅λλ€.")
}
}
precondition: λλ²κ·Έμ νλ‘λμ λΉλ λͺ¨λμμ 쑰건μ νμΈνκ³ , μ‘°κ±΄μ΄ falseλ©΄ μ±μ μ’ λ£νλ ν¨μμ λλ€.
preconditionFailure: 쑰건 νμΈ μμ΄ λ°λ‘ μ±μ μ’ λ£νλ ν¨μμ λλ€.
fatalError: μ΅μ ν μ€μ κ³Ό κ΄κ³μμ΄ νμ μ±μ μ’ λ£νλ ν¨μμ λλ€.
π μμ½
Swiftμ κΈ°λ³Έ κ°λ μ€ μ£Όμ λ΄μ©μ μ 리νμ΅λλ€:
- λΆμΈ(Bool): μ°Έ/κ±°μ§ κ°μ νννλ λ Όλ¦¬ νμ
- νν(Tuple): μ¬λ¬ κ°μ νλμ λ³΅ν© κ°μΌλ‘ κ·Έλ£Ήν
- μ΅μ
λ(Optional): κ°μ΄ μκ±°λ μμ μ μλ μν©μ μμ νκ² μ²λ¦¬
- nil: κ°μ΄ μμμ λνλ΄λ νΉμ κ°
- μ΅μ λ λ°μΈλ©: if letμ μ¬μ©ν΄ μ΅μ λ κ°μ μμ νκ² μΆμΆ
- nil-κ²°ν© μ°μ°μ(??): κΈ°λ³Έκ° μ 곡
- κ°μ μΈλν(!): μ΅μ λμμ κ°μ κ°μ λ‘ μΆμΆ
- μλ¬ μ²λ¦¬: do-try-catch ꡬ문μ μ¬μ©ν μλ¬ μ²λ¦¬ λ©μ»€λμ¦
- μμ€κ³Ό μ μ 쑰건: λ°νμμ μ½λμ 쑰건μ νμΈνλ λ°©λ²
'π₯ Bread Basics > Swift' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
Swift 곡μ λ¬Έμ μ 리 - ν΄λ‘μ (Closures) (0) | 2025.04.11 |
---|---|
Swift 곡μ λ¬Έμ μ 리 - ν¨μ (Functions) (0) | 2025.04.11 |
Swift 곡μ λ¬Έμ μ 리 - μ μ΄ νλ¦ (Control Flow) (0) | 2025.04.10 |
Swift 곡μ λ¬Έμ μ 리 - 컬λ μ νμ (Collection Types) (0) | 2025.04.10 |
Swift 곡μ λ¬Έμ μ 리 - λ¬Έμμ΄κ³Ό λ¬Έμ (Strings and Characters) (0) | 2025.04.10 |
Swift 곡μ λ¬Έμ μ 리 - κΈ°λ³Έ μ°μ°μ (Basic Operators) (0) | 2025.04.10 |
Swift 곡μ λ¬Έμ μ 리 - κΈ°λ³Έ(The Basics)(1/2) (0) | 2025.04.10 |
Swift 곡μ λ¬Έμ μ 리 - A Swift Tour (0) | 2025.04.10 |