λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
⌨️ Language/swift

[Swift] μ˜ˆμ™Έ μ²˜λ¦¬μ™€ ν•¨μˆ˜

by hyebin (Helia) 2024. 3. 17.
λ°˜μ‘ν˜•

1. μ˜ˆμ™Έ 처리

였λ₯˜ 처리의 κ°œλ…

  • ν”„λ‘œκ·Έλž¨μ— μ—λŸ¬κ°€ λ°œμƒν–ˆμ„ λ•Œ, 이λ₯Ό κ°μ§€ν•˜κ³  λ³΅κ΅¬ν•˜λŠ” ν”„λ‘œμ„ΈμŠ€
  • λͺ¨λ“  ν”„λ‘œκ·Έλž¨μ΄ 항상 μ›ν•˜λŠ”λŒ€λ‘œ μ •ν™•νžˆ λ™μž‘ν•œλ‹€λŠ” 보μž₯이 μ—†κΈ° λ•Œλ¬Έμ— 였λ₯˜κ°€ λ°œμƒν•  수 μžˆμŒμ„ 항상 κ³ λ €ν•΄μ•Ό 함

guard

guard 쑰건 else {쑰건이 거짓일 λ•Œ 싀행될 ꡬ문}

// someValue κ°€ 0이 아닐 κ²½μš°μ—λ§Œ 좜λ ₯
guard someValue != 0 else { return }
print(someValue)
  • 쑰건듀을 κ±ΈλŸ¬λ‚Ό λ•Œ μ‚¬μš©
  • 가독성을 μœ„ν•΄ μ‚¬μš©
    • 쑰건식에 이 ν•¨μˆ˜κ°€ μˆ˜ν–‰ν•˜λŠ”λ° ν•„μš”ν•œ 쑰건을 κ·ΈλŒ€λ‘œ μ λŠ”λ‹€λŠ” μ μ—μ„œ guard ꡬ문이 μ½”λ“œλ₯Ό 뢄석할 λ•Œ 가독성이 쒋아짐
func printMessage(_ message: String?) {
	if message == nil { return }
    print(message!) // 이미 nil 검사λ₯Ό ν–ˆμŒ!
}
printMessage(string)

func printMessage(_ message: String?) {
	guard message != nil else { return }
    print(message!)
}
printMessage(string)
  • μ˜΅μ…”λ„ 바인딩
    • guardλ₯Ό μ‚¬μš©ν•˜λ©΄ if λ‘œ μ˜΅μ…”λ„ λ°”μΈλ”©ν–ˆμ„ λ•Œμ™€ 달리 { } κ΄„ν˜Έ λ°–μ—μ„œλ„ μ‚¬μš© κ°€λŠ₯
var string:String? = "hello"

func printMessage(_ message: String?) {
    guard let letMessage = message else { return }
    print(letMessage)
}
printMessage(string)

func printMessage(_ message: String?) {
    if let letMessage = message{
        print(letMessage)
    } else { return }
}
printMessage(string)

 

do-catch

  • throw
    • 였λ₯˜ λ˜μ§€κΈ°(였λ₯˜λ₯Ό λ˜μ§„λ‹€ = 였λ₯˜λ₯Ό μ²˜λ¦¬ν•΄μ£ΌλŠ” 곳으둜 전달해쀀닀)
      1. throwsλŠ” 였λ₯˜κ°€ λ°œμƒν•  κ°€λŠ₯성이 μžˆλŠ” λ©”μ†Œλ“œ 제λͺ© μ˜†μ— μž‘μ„±
      2. throw ( ‘s’ μ—†μŒ)은 였λ₯˜κ°€ λ°œμƒν•  ꡬ간에 μž‘μ„±
func printNumber(_ number: Int)throws -> Int {
// 1   
var text = ""
   guard number > 0 else {
throw TestError.outOfRange 
// 2   
}    
return text
}
  • try
    • ‘이 ν•¨μˆ˜κ°€ 였λ₯˜κ°€ λ°œμƒν•  μˆ˜λ„ μžˆλŠ”λ°, ν•œλ²ˆ μ‹œλ„ν•΄λ³Όκ²Œμš”.’
let resultNumber = try object.printNumber(-20)
  • do-catch
do {  
   let resultNumber = try object.printNumber(-20)
// μœ„μ˜ ν•¨μˆ˜κ°€ 였λ₯˜μ΄ ν•¨μˆ˜κ°€ 였λ₯˜κ°€ λ°œμƒν•  μˆ˜λ„ μžˆλŠ”λ°, ν•œλ²ˆ μ‹œλ„ν•΄λ³Όκ²Œμš”.

} catch {
   print(error)
// 였λ₯˜λ₯Ό 작으면 errorλ₯Ό ν”„λ¦°νŠΈν•©λ‹ˆλ‹€.
}

 

2.ν•¨μˆ˜

ν•¨μˆ˜μ˜ μ •μ˜

  • ν•¨μˆ˜λŠ” νŠΉμ • μž‘μ—…μ„ μˆ˜ν–‰ν•˜κΈ° μœ„ν•΄ ν•¨κ»˜ κ΅¬μ„±λœ 일련의 λͺ…λ Ήλ¬Έ
  • ν•¨μˆ˜λ₯Ό μ„ μ–Έν•  λ•ŒλŠ” func ν‚€μ›Œλ“œ μ‚¬μš©
  • (n: Int) → Int 와 같은 ν˜•μ‹μœΌλ‘œ νŒŒλΌλ―Έν„°μ™€ λ°˜ν™˜ν˜•μ„ μ •μ˜
  • νŒŒλΌλ―Έν„°μ™€ λ°˜ν™˜ 값은 λͺ¨λ“  νƒ€μž…μœΌλ‘œ μ„ μ–Έ κ°€λŠ₯(Int, String, Bool, Array, optional…)
  • νŒŒλΌλ―Έν„°λŠ” let으둜 λ³€κ²½ λΆˆκ°€
/*
func ν•¨μˆ˜λͺ… (νŒŒλΌλ―Έν„°: 데이터 νƒ€μž…) -> λ°˜ν™˜νƒ€μž… {
	return
}
*/

func add(n: Int) -> Int {
	return n+2
}

let result = add(n: 2)
print(result) //4

 

ν•¨μˆ˜μ˜ ν•„μš”μ„±

  1. μž¬μ‚¬μš©μ„±
    • ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜λ©΄ λ™μΌν•œ μ½”λ“œλ₯Ό λ°˜λ³΅ν•΄μ„œ λ‹€μ‹œ μž‘μ„±ν•˜μ§€ μ•Šκ³ λ„ μ—¬λŸ¬ 번 μž¬μ‚¬μš©ν•  수 μžˆλŠ” μ½”λ“œλ₯Ό μž‘μ„±ν•  수 있음
    • λ³΅μž‘ν•˜κ±°λ‚˜ 반볡적인 μž‘μ—…μ„ μ²˜λ¦¬ν•  λ•Œ λ§Žμ€ μ‹œκ°„κ³Ό λ…Έλ ₯을 μ ˆμ•½ν•  수 있음
  2. λͺ¨λ“ˆμ„±
    • ν•¨μˆ˜λŠ” λ³΅μž‘ν•œ μž‘μ—…μ„ 더 μž‘κ³  κ΄€λ¦¬ν•˜κΈ° μ‰¬μš΄ μ½”λ“œ 쑰각으둜 λΆ„ν•΄ν•˜μ—¬ μ΄ν•΄ν•˜κ³  μœ μ§€ κ΄€λ¦¬ν•˜κΈ° 쉬움
    • μ½”λ“œλ₯Ό λͺ¨λ“ˆν™”ν•˜μ—¬ λ…λ¦½μ μœΌλ‘œ ν…ŒμŠ€νŠΈν•˜κ³  디버깅할 수 μžˆλŠ” λ³„λ„μ˜ ꡬ성 μš”μ†Œλ‘œ λ‚˜λˆŒ 수 μžˆμŒμ„ 의미
  3. 좔상화
    • ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜λ©΄ μž‘μ—…μ˜ κ΅¬ν˜„ μ„ΈλΆ€ 사항을 μΆ”μƒν™”ν•˜κ³  μž‘μ—…μ„ μˆ˜ν–‰ν•˜κΈ° μœ„ν•œ κ³ κΈ‰ μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ œκ³΅ν•  수 있음
    • κ΅¬ν˜„ μ„ΈλΆ€ 사항에 μ΅μˆ™ν•˜μ§€ μ•Šμ€ λ‹€λ₯Έ 개발자λ₯Ό μœ„ν•΄ μ½”λ“œλ₯Ό 더 읽기 쉽고 μ‚¬μš©ν•˜κΈ° μ‰½κ²Œ λ§Œλ“­λ‹ˆλ‹€.
  4. μΊ‘μŠν™”
    • ν•¨μˆ˜λŠ” μ½”λ“œμ™€ 데이터λ₯Ό μΊ‘μŠν™”ν•˜λŠ” 데 도움이 됨
    • 즉, μž‘μ—…μ˜ κ΅¬ν˜„ μ„ΈλΆ€ 정보λ₯Ό 숨길 수 있고 μ½”λ“œμ™€ μƒν˜Έ μž‘μš©ν•˜κΈ° μœ„ν•œ 곡용 μΈν„°νŽ˜μ΄μŠ€λ§Œ λ…ΈμΆœν•  수 있음
    • μ˜λ„ν•˜μ§€ μ•Šμ€ λΆ€μž‘μš©μ΄λ‚˜ μ½”λ“œμ˜ λ‹€λ₯Έ λΆ€λΆ„κ³Όμ˜ μƒν˜Έ μž‘μš©μ„ λ°©μ§€ν•  수 있음
  5. μ½”λ“œ ꡬ성
    • ν•¨μˆ˜λŠ” μ½”λ“œλ₯Ό 논리적 그룹으둜 κ΅¬μ„±ν•˜μ—¬ μ½”λ“œλ₯Ό 더 μ‰½κ²Œ νƒμƒ‰ν•˜κ³  이해할 수 μžˆλ„λ‘ λ„μ™€μ€Œ
    • μ½”λ“œ 쀑볡을 λ°©μ§€ν•˜κ³  μ½”λ“œλ² μ΄μŠ€μ˜ μ „λ°˜μ μΈ λ³΅μž‘μ„±μ„ μ€„μ΄λŠ” 데 도움이 될 수 있음

 

νŒŒλΌλ―Έν„°(Parameters)와 λ°˜ν™˜ κ°’

  • νŒŒλΌλ―Έν„°κ°€ μ—†λŠ” ν•¨μˆ˜
func sayHelloWorld() -> String {
 return "hello, world"
}
print(sayHelloWorld()) // hello, world
  • μ—¬λŸ¬κ°œμ˜ νŒŒλΌλ―Έν„°λ₯Ό μ‚¬μš©ν•˜λŠ” ν•¨μˆ˜
func add(a: Int, b: Int) -> Int {
 return a+b
}
print(add(a: 3, b: 4)) // 7
  • λ°˜ν™˜ 값이 μ—†λŠ” ν•¨μˆ˜μ—¬λŸ¬κ°œμ˜ 값을 λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜ (νŠœν”Œλ‘œ λ°˜ν™˜)
func calculator(a: Int, b: Int) -> (sum: Int, sub: Int) {
 return (a+b, a-b)
}

let result = calculator(a: 3, b: 4)
print(result.sum, result.sub) // (7, -1)

 

ν•¨μˆ˜ 인자 라벨과 νŒŒλΌλ―Έν„° 이름

  • 인자 라벨 μ§€μ •: ν•¨μˆ˜ 호좜 μ‹œ μ‚¬μš©ν•  νŒŒλΌλ―Έν„° 이름 μ§€μ •
func printName(insertName name: String){
    print( "my Name is " + name + ".")  //my Name is hyebin.
}
 
printName(insertName: "hyebin")
  • 인자 μƒλž΅: νŒŒλΌλ―Έν„° μ•žμ— “_”λ₯Ό λΆ™μ—¬ ν•¨μˆ˜ 호좜 μ‹œ νŒŒλΌλ―Έν„° 이름 μƒλž΅
func printName(_ name: String, _ age: Int){
    print( name, age)  //hyebin 14
}
 
printName("hyebin" , 14)
  • κΈ°λ³Έ νŒŒλΌλ―Έν„° κ°’
    • ν•¨μˆ˜μ˜ νŒŒλΌλ―Έν„°μ— κΈ°λ³Έ 값을 μ„€μ •
    • 기본값이 μ„€μ •λœ νŒŒλΌλ―Έν„°λŠ” ν•¨μˆ˜ 호좜 μ‹œ μƒλž΅ κ°€λŠ₯
func printName(name: String, age: Int = 24){
    print( name, age)  //hyebin 24
}
 
printName(name: "hyebin")  //hyebin 24
printName(name: "yyy", age: 90)  //yyy 90
  • κ°€λ³€ νŒŒλΌλ―Έν„°
    • νŒŒλΌλ―Έν„° 데이터 νƒ€μž… 뒀에 ... ν‚€μ›Œλ“œ μ‚¬μš©
    • κ°€λ³€ νŒŒλΌλ―Έν„° 뒀에 μžˆλŠ” νŒŒλΌλ―Έν„°λŠ” 인자 μƒλž΅ λΆˆκ°€
    • 기본값을 κ°€μ§ˆ 수 μ—†μœΌλ©°, ν•˜λ‚˜μ˜ νŒŒλΌλ―Έν„°μ—μ„œλ§Œ μ‚¬μš© κ°€λŠ₯
    • μž…λ ₯ κ°’μ˜ μˆ˜κ°€ 사전에 μ•Œλ €μ§€μ§€ μ•Šκ³  λŸ°νƒ€μž„ μ‹œ λ‹¬λΌμ§ˆ 수 μžˆλŠ” κ²½μš°μ— 유용
    • κ°€λ³€ νŒŒλΌλ―Έν„°λ‘œ μ „λ‹¬λœ 값은 ν•¨μˆ˜ λ‚΄λΆ€μ˜ λ°°μ—΄λ‘œ μˆ˜μ§‘
func avg(_ numbers: Double...) -> Double {
    var total: Double = 0
    for number in numbers {
        total += number
    }
    return total / Double(numbers.count)
}
print(avg(1, 2, 3, 4, 5))  // 3.0
print(avg(3, 8.25, 18.75)) //10.0
  • 인-아웃 νŒŒλΌλ―Έν„°
    • ν•¨μˆ˜μ—μ„œ 직접 νŒŒλΌλ―Έν„° 값에 μ ‘κ·Όν•  수 μžˆλ„λ‘ ν•˜λŠ” νŒŒλΌλ―Έν„° (νŒŒλΌλ―Έν„°λ₯Ό var둜 μ‚¬μš©)
    • ν•¨μˆ˜μ˜ μΈμžμ— λ³€μˆ˜λ₯Ό 넣을 λ•Œ & ν‚€μ›Œλ“œ μ‚¬μš©
    • ν•¨μˆ˜ λ‚΄λΆ€μ˜ λ³€μˆ˜ 값을 μˆ˜μ •ν•΄μ•Ό ν•˜κ³  ν•΄λ‹Ή λ³€κ²½ 사항을 ν•¨μˆ˜ 외뢀에도 λ°˜μ˜ν•˜κ³ μž ν•  λ•Œ 유용
    • in-out λ§€κ°œλ³€μˆ˜λŠ” λ³€μˆ˜μ—λ§Œ μ‚¬μš©ν•  수 있음
func swapTwoInts(_ a: inout Int, _ b: inout Int) {
    let temporaryA = a
    a = b
    b = temporaryA
}
 
var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)
print("someInt is now \\(someInt), and anotherInt is now \\(anotherInt)")
// someInt is now 107, and anotherInt is now 3

 

ν•¨μˆ˜ νƒ€μž…

  • λͺ¨λ“  ν•¨μˆ˜λŠ” νŒŒλΌλ―Έν„° ν˜•κ³Ό(parameter types) λ°˜ν™˜ ν˜•(return type)으둜 κ΅¬μ„±λœ νŠΉμ •ν•œ ν•¨μˆ˜ νƒ€μž…μ„ 가짐
  • λ³€μˆ˜ ν˜•μœΌλ‘œ
    • λ³€μˆ˜ λ˜λŠ” μƒμˆ˜ μœ ν˜•μœΌλ‘œ μ‚¬μš© κ°€λŠ₯
    • ν•¨μˆ˜λ₯Ό κ°’μœΌλ‘œ μ €μž₯ν•˜κ³  λ‚˜μ€‘μ— 호좜 κ°€λŠ₯
    • λ³€μˆ˜λ‚˜ μƒμˆ˜μ— ν•¨μˆ˜λ₯Ό ν• λ‹Ήν•  λ•Œ ν•¨μˆ˜ ν˜•μ„ μ„ μ–Έν•˜μ§€ μ•Šμ•„λ„ νƒ€μž… μΆ”λ‘ ν•΄ μžλ™μœΌλ‘œ ν•¨μˆ˜ ν• λ‹Ή κ°€λŠ₯
func addTwoInts(_ a: Int, _ b: Int) -> Int {
  return a + b
}
 
var mathFunction: (Int, Int) -> Int = addTwoInts
//var mathFunction = addTwoInts
 
print(mathFunction(2,3))//5
  • νŒŒλΌλ―Έν„° ν˜•μœΌλ‘œ
    • ν•¨μˆ˜μ— λŒ€ν•œ νŒŒλΌλ―Έν„°μ˜ νƒ€μž…μœΌλ‘œ μ‚¬μš© κ°€λŠ₯
    • ν•¨μˆ˜λ₯Ό λ‹€λ₯Έ ν•¨μˆ˜μ˜ 인수둜 전달할 수 있으며 μ „λ‹¬λœ ν•¨μˆ˜λ₯Ό 호좜 κ°€λŠ₯
func addTwoInts(_ a: Int, _ b: Int) -> Int {
  return a + b
}
 
func printMathResult(_ mathFunction: (Int, Int) -> Int, _ a: Int, _ b: Int) {
    print("Result: \\(mathFunction(a, b))")
}
printMathResult(addTwoInts, 3, 5) //"Result: 8"
  • λ°˜ν™˜ν˜•μœΌλ‘œ
    • ν•¨μˆ˜μ˜ λ°˜ν™˜ νƒ€μž…μœΌλ‘œλ„ μ‚¬μš© κ°€λŠ₯
    • ν•¨μˆ˜μ—μ„œ ν•¨μˆ˜λ₯Ό λ°˜ν™˜ κ°€λŠ₯
func stepForward(_ input: Int) -> Int {
    return input + 1
}
func stepBackward(_ input: Int) -> Int {
    return input - 1
}
func chooseStepFunction(backward: Bool) -> (Int) -> Int {
    return backward ? stepBackward : stepForward
}
var currentValue = 3
let moveNearerToZero = chooseStepFunction(backward: currentValue > 0)
 
while currentValue != 0 {
    print("\\(currentValue)... ")
    currentValue = moveNearerToZero(currentValue)
}
print("zero!")

/*
3... 
2... 
1... 
zero!
*/

 

μ€‘μ²©ν•¨μˆ˜

  • 쀑첩 ν•¨μˆ˜λŠ” λ‚΄λΆ€ ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜μ—¬ μ™ΈλΆ€ ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λŠ” κΈ°λŠ₯을 제곡
func calcDecrement(forDecrement total: Int) -> () -> Int {
    var overallDecrement = 0
    
    func decrementer() -> Int {
        overallDecrement -= total
        return overallDecrement
     }
    
    return decrementer
}

let decrem = calcDecrement(forDecrement: 30)
print(decrem()) // -30
  • ν•¨μˆ˜μ˜ μ˜€λ²„λ‘œλ”©(Overloading)
    • ν•¨μˆ˜ 이름은 κ°™μ§€λ§Œ νŒŒλΌλ―Έν„°, λ¦¬ν„΄νƒ€μž… 등을 λ‹€λ₯΄κ²Œ ν•˜μ—¬ ν•¨μˆ˜λ₯Ό μ€‘λ³΅μœΌλ‘œ μ„ μ–Έ
    • 같은 μ΄λ¦„μ˜ ν•¨μˆ˜λ₯Ό μ„ μ–Έν•˜λ©΄ 였λ₯˜ λ°œμƒ
    • νŒŒλΌλ―Έν„°μ™€ λ¦¬ν„΄νƒ€μž…μ„ λ‹€λ₯΄κ²Œ ν•˜λ©΄ 였λ₯˜κ°€ λ°œμƒν•˜μ§€ μ•ŠμŒ
    • 같은 λ™μž‘μ„ ν•˜μ§€λ§Œ νŒŒλΌλ―Έν„° νƒ€μž…, 리턴 νƒ€μž…μ΄ λ‹€λ₯Έ ν•¨μˆ˜λ₯Ό 같은 μ΄λ¦„μœΌλ‘œ μ„ μ–Έν•˜μ—¬ μ½”λ“œλ₯Ό μ§κ΄€μ μœΌλ‘œ μž‘μ„± κ°€λŠ₯
func sum() { }
func sum() { }      // Invalid redeclaration of 'sum()'
func sum() { }
func sum(n: Int) { }
func sum() -> Int { return 0 }
// λͺ¨λ‘ 두 수λ₯Ό λ”ν•˜λŠ” λ™μž‘μ„ ν•˜μ§€λ§Œ νƒ€μž…μ— 따라 이름이 달라짐
func sumInt(_ a: Int, _ b: Int) -> Int {
    return a + b
}
 
func sumDouble(_ a: Double, _ b: Double) -> Double {
    return a + b
}
 
func sumString(_ a: String, _ b: String) -> String {
    return a + b
}

// sum으둜 ν•¨μˆ˜μ˜ 이름을 λ™μΌν•˜κ²Œ ν•˜κ³ , νŒŒλΌλ―Έν„°μ™€ 리턴 κ°’μ˜ νƒ€μž…λ§Œ λ³€κ²½
func sum(_ a: Int, _ b: Int) -> Int {
    return a + b
}
 
func sum(_ a: Double, _ b: Double) -> Double {
    return a + b
}
 
func sum(_ a: String, _ b: String) -> String {
    return a + b
}

 

β“ν•¨μˆ˜μ™€ λ©”μ„œλ“œμ˜ 차이

λ©”μ„œλ“œ: ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λŠ” 객체가 μžˆλŠ” 경우 → a.remove()

ν•¨μˆ˜: ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λŠ” 객체가 μ—†λŠ” 경우 → func remvoe(), remove()

λ°˜μ‘ν˜•