λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
iOS 🍎/Swift

Swift09 - ν΄λ‘œμ €

by yongmin.Lee 2021. 2. 2.

Closures

Closures are self-contained blocks of functionality that can be passed around and used in your code. Closures in Swift are similar to blocks in C and Objective-C and to lambdas in other programming languages.

 

ν΄λ‘œμ €λž€?

ν΄λ‘œμ €λŠ” μ‹€ν–‰κ°€λŠ₯ν•œ μ½”λ“œ λΈ”λŸ­μž…λ‹ˆλ‹€.

ν•¨μˆ˜μ™€ λ‹€λ₯΄κ²Œ μ΄λ¦„μ •μ˜λŠ” ν•„μš”ν•˜μ§€λŠ” μ•Šμ§€λ§Œ, λ§€κ°œλ³€μˆ˜ 전달과 λ°˜ν™˜ 값이 쑴재 ν•  수 μžˆλ‹€λŠ” 점이 λ™μΌν•©λ‹ˆλ‹€.

ν•¨μˆ˜λŠ” 이름이 μžˆλŠ” ν΄λ‘œμ €μž…λ‹ˆλ‹€.

μΌκΈ‰κ°μ²΄λ‘œ μ „λ‹¬μΈμž, λ³€μˆ˜, μƒμˆ˜ 등에 μ €μž₯ 및 전달이 κ°€λŠ₯ν•©λ‹ˆλ‹€.

ν΄λ‘œμ €λŠ” ν•¨μˆ˜μ˜ μ „λ‹¬μΈμžμΈ μ½œλ°±ν•¨μˆ˜λ‘œ 주둜 μ‚¬μš©λœλ‹€

 

κΈ°λ³Έ ν΄λ‘œμ € 문법

ν΄λ‘œμ €λŠ” μ€‘κ΄„ν˜Έ { }둜 κ°μ‹Έμ ΈμžˆμŠ΅λ‹ˆλ‹€.

κ΄„ν˜Έλ₯Ό μ΄μš©ν•΄ νŒŒλΌλ―Έν„°λ₯Ό μ •μ˜ν•©λ‹ˆλ‹€.

-> 을 μ΄μš©ν•΄ λ°˜ν™˜ νƒ€μž…μ„ λͺ…μ‹œν•©λ‹ˆλ‹€.

"in" ν‚€μ›Œλ“œλ₯Ό μ΄μš©ν•΄ μ‹€ν–‰ μ½”λ“œμ™€ λΆ„λ¦¬ν•©λ‹ˆλ‹€.

{ (λ§€κ°œλ³€μˆ˜ λͺ©λ‘) -> λ°˜ν™˜νƒ€μž… in
    μ‹€ν–‰ μ½”λ“œ
}

 

κΈ°λ³Έ ν΄λ‘œμ € ν‘œν˜„

// sumClosure μƒμˆ˜μ— ν΄λ‘œμ €λ₯Ό ν• λ‹Ή
let sumClosure: (Int, Int) -> Int = { (a: Int, b: Int) in
    return a + b
}

let sumResult: Int = sumClosure(1, 2)
print(sumResult) // 3

 

ν•¨μˆ˜ vs ν΄λ‘œμ €

let sumClosure: (Int, Int) -> Int = { (a: Int, b: Int) in
    return a + b
}

func sumFunction(a: Int, b: Int) -> Int {
	return a + b
}

var result1: Int = sumClosure(3,4) // 7
var result2: Int = sumFunction(a:1, b:3) // 4

 

ν΄λ‘œμ € μΆ•μ•½1 : ν›„ν–‰ ν΄λ‘œμ €, trailing closure

ν΄λ‘œμ €κ°€ ν•¨μˆ˜μ˜ λ§ˆμ§€λ§‰ μ „λ‹¬μΈμžμΌλ•Œ, λ§ˆμ§€λ§‰ λ§€κ°œλ³€μˆ˜ 이름을 μƒλž΅ν•œ ν›„ ν•¨μˆ˜ μ†Œκ΄„ν˜Έ 외뢀에 ν΄λ‘œμ €λ₯Ό κ΅¬ν˜„

// ν΄λ‘œμ €λ₯Ό λ§€κ°œλ³€μˆ˜λ‘œ κ°–λŠ” ν•¨μˆ˜ calculated(a:b:method:)
func calculate(a: Int, b: Int, method: (Int, Int) -> Int) -> Int {
    return method(a, b)
}

// ν•¨μˆ˜ 결과값을 μ €μž₯ν•  λ³€μˆ˜
var result: Int

// ν›„ν–‰ ν΄λ‘œμ €
result = calculate(a: 10, b: 10) { (left: Int, right: Int) -> Int in
    return left + right
}
print(result) // 20

 

ν΄λ‘œμ € μΆ•μ•½2 : ν΄λ‘œμ € λ°˜ν™˜νƒ€μž… μƒλž΅

calculate(a:b:method:) ν•¨μˆ˜μ˜ method λ§€κ°œλ³€μˆ˜λŠ” Int νƒ€μž…을 λ°˜ν™˜ν•  κ²ƒμ΄λΌλŠ” 사싀을 μ»΄νŒŒμΌλŸ¬λ„ μ•ŒκΈ° λ•Œλ¬Έμ— ꡳ이 ν΄λ‘œμ €μ—μ„œ λ°˜ν™˜νƒ€μž…μ„ λͺ…μ‹œν•΄ 주지 μ•Šμ•„λ„ λ©λ‹ˆλ‹€. λŒ€μ‹  in ν‚€μ›Œλ“œλŠ” μƒλž΅ν•  수 μ—†μŠ΅λ‹ˆλ‹€

// ν΄λ‘œμ €λ₯Ό λ§€κ°œλ³€μˆ˜λ‘œ κ°–λŠ” ν•¨μˆ˜ calculated(a:b:method:)
func calculate(a: Int, b: Int, method: (Int, Int) -> Int) -> Int {
    return method(a, b)
}

// ν•¨μˆ˜ 결과값을 μ €μž₯ν•  λ³€μˆ˜
var result: Int

// ν΄λ‘œμ €μ˜ λ°˜ν™˜νƒ€μž… μƒλž΅
result = calculate(a: 10, b: 10, method: { (left: Int, right: Int) in
    return left + right
})

print(result) // 20

 

ν΄λ‘œμ € μΆ•μ•½3 : ν΄λ‘œμ € 단좕 μΈμžμ΄λ¦„

ν΄λ‘œμ €μ˜ λ§€κ°œλ³€μˆ˜ 이름이 ꡳ이 λΆˆν•„μš”ν•˜λ‹€λ©΄ 단좕 μΈμžμ΄λ¦„μ„ ν™œμš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 단좕 μΈμžμ΄λ¦„μ€ ν΄λ‘œμ €μ˜ λ§€κ°œλ³€μˆ˜μ˜ μˆœμ„œλŒ€λ‘œ $0, $1, $2... 처럼 ν‘œν˜„

// ν΄λ‘œμ €λ₯Ό λ§€κ°œλ³€μˆ˜λ‘œ κ°–λŠ” ν•¨μˆ˜ calculated(a:b:method:)
func calculate(a: Int, b: Int, method: (Int, Int) -> Int) -> Int {
    return method(a, b)
}

// ν•¨μˆ˜ 결과값을 μ €μž₯ν•  λ³€μˆ˜
var result: Int

// ν΄λ‘œμ €μ˜ 단좕 μΈμžμ΄λ¦„
result = calculate(a: 10, b: 10, method: {
    return $0 + $1
})

print(result) // 20

 

ν΄λ‘œμ € μΆ•μ•½4 : μ•”μ‹œμ  λ°˜ν™˜ ν‘œν˜„

ν΄λ‘œμ €κ°€ λ°˜ν™˜ν•˜λŠ” 값이 μžˆλ‹€λ©΄ ν΄λ‘œμ €μ˜ λ§ˆμ§€λ§‰ μ€„μ˜ 결과값은 μ•”μ‹œμ μœΌλ‘œ λ°˜ν™˜κ°’μœΌλ‘œ μ·¨κΈ‰ν•©λ‹ˆλ‹€.

// ν΄λ‘œμ €λ₯Ό λ§€κ°œλ³€μˆ˜λ‘œ κ°–λŠ” ν•¨μˆ˜ calculated(a:b:method:)
func calculate(a: Int, b: Int, method: (Int, Int) -> Int) -> Int {
    return method(a, b)
}

// ν•¨μˆ˜ 결과값을 μ €μž₯ν•  λ³€μˆ˜
var result: Int

// ν΄λ‘œμ € μ•”μ‹œμ  λ°˜ν™˜
result = calculate(a: 10, b: 10) {
    $0 + $1
}

print(result) // 20

 

ν΄λ‘œμ € μΆ•μ•½ 비ꡐ

//μΆ•μ•½ μ „
result = calculate(a: 10, b: 10, method: { (left: Int, right: Int) -> Int in
    return left + right
})

//μΆ•μ•½ ν›„
result = calculate(a: 10, b: 10) { $0 + $1 }

print(result) // 20