์ƒˆ์†Œ์‹

๐Ÿ“ฑ iOS/-- Swift 5

(Swift) - ํด๋กœ์ € (Closure)

  • -

ํด๋กœ์ €(Closure) ๋ž€?

๊ฐ„๋‹จํ•˜๊ฒŒ ๋งํ•˜๋ฉด ํด๋กœ์ €๋Š” ์ผ์ • ๊ธฐ๋Šฅ์„ ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ { } ๋กœ ๋ชจ์•„๋†“์€๊ฒƒ์„ ๋งํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ผ๋ฐ˜์ ์ธ func ๋กœ ์„ ์–ธ๋˜๋Š” ํ•จ์ˆ˜์˜ ์ƒ์œ„๊ฐœ๋…์ด ํด๋กœ์ €์ด๋‹ค.

์™œ ํด๋กœ์ €๋ผ๊ณ  ํ•˜์ง€?

ํด๋กœ์ €๋Š” ๋ณ€์ˆ˜, ์ƒ์ˆ˜๊ฐ€ ์„ ์–ธ๋œ ์Šค์ฝ”ํ”„์—์„œ ์ฐธ์กฐ๋ฅผ ์บก์ณ(์ €์žฅ) ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ ์ด๊ฑธ ํด๋กœ์ง•์ด๋ผ๊ณ  ํ•˜๋ฉฐ ๊ทธ๋ž˜์„œ ํด๋กœ์ €๋ผ๊ณ  ์ด๋ฆ„๋ถ™์—ฌ์กŒ๋‹ค.

ํด๋กœ์ €๋ฅผ ์™œ ์“ฐ๋‚˜?

์Šค์œ„ํ”„ํŠธ๋Š” ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํŒจ๋Ÿฌ๋‹ค์ž„์ด๋ผ๊ณ  ํ•˜๋Š”๋ฐ, ์ด๋Ÿฌํ•œ ์Šคํƒ€์ผ์— ํด๋กœ์ €๊ฐ€ ์ค‘์š”ํ•œ ์—ญํ• ์„ ํ•œ๋‹ค. ํด๋กœ์ €๋ฅผ ์ œ๋„ค๋ฆญ, ํ”„๋กœํ† ์ฝœ, ๋ชจ๋‚˜๋“œ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋ฉด์„œ ์Šค์œ„ํ”„ํŠธ๋Š” ๋” ๊ฐ•๋ ฅํ•œ ์–ธ์–ด๊ฐ€ ๋  ์ˆ˜์žˆ๋‹ค.

ํด๋กœ์ €์˜ ํ˜•ํƒœ(์ข…๋ฅ˜)

  1. ์ด๋ฆ„์ด ์žˆ๊ณ , ๊ฐ’์„ ์บก์ณํ•˜์ง€ ์•Š๊ณ , ์ „์—ญํ•จ์ˆ˜์˜ ํ˜•ํƒœ
  2. ์ด๋ฆ„์ด ์žˆ๊ณ , ๋‹ค๋ฅธ ํ•จ์ˆ˜์˜ ๊ฐ’์„ ์บก์ณํ•˜๋Š” ์ค‘์ฒฉ๋œ(nested) ํ•จ์ˆ˜ ํ˜•ํƒœ
  3. ์ด๋ฆ„ ์—†๊ณ , ์ฃผ๋ณ€ context์— ๋”ฐ๋ผ์„œ ๊ฐ’์„ ์บก์ณํ• ์ˆ˜ ์žˆ๋Š” ์ถ•์•ฝ ํ•จ์ˆ˜ํ˜•ํƒœ.

ํด๋กœ์ €์˜ ํ‘œํ˜„๋ฐฉ๋ฒ•

 

์™„์ „ํ•˜๊ฒŒ ๋™์น˜์ธ ์ฝ”๋“œ๋ผ๋„, ํด๋กœ์ €๋Š” ํ‘œํ˜„๋ฐฉ๋ฒ•์ด ์—ฌ๋Ÿฌ๊ฐ€์ง€์ด๊ธฐ ๋•Œ๋ฌธ์— ์–ด๋ ต๊ฒŒ ๋Š๊ปด์ง€๋Š”๊ฒƒ๊ฐ™๋‹ค.

  1. parameter์˜ ํƒ€์ž…, ๋ฐ˜ํ™˜ ๊ฐ’์˜ ํƒ€์ž…์„ ์ƒ๋žตํ•  ์ˆ˜ ์žˆ๋‹ค. (swift๋Š” ํƒ€์ž… ์ถ”๋ก ์ด ๊ฐ€๋Šฅํ•˜๋ฏ€๋กœ)
  2. ํด๋กœ์ € ๋ธ”๋Ÿญ ์•ˆ์— ์ฝ”๋“œ๊ฐ€ ํ•œ์ค„์ด๋ผ๋ฉด, ์•”์‹œ์ ์œผ๋กœ ์ด๋ฅผ ๋ฐ˜ํ™˜๊ฐ’ ์ฒ˜๋ฆฌํ•œ๋‹ค.
  3. ์ถ•์•ฝ๋œ argument name ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ($0... $1... ๋“ฑ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š”๊ฒƒ)
  4. ํ›„ํ–‰ ํด๋กœ์ €(trailing closure) ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

 

a * b ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํด๋กœ์ €

์•„๋ž˜ 3๊ฐœ์˜ ํด๋กœ์ €๋Š” ๋ชจ๋‘ ๊ฐ™์€ ์ฝ”๋“œ์ด๋‹ค.

var multiply: (Int, Int) -> Int = { (a: Int, b:Int) -> Int in
    return a * b
}

/// - ํŒŒ๋ผ๋ฏธํ„ฐ(๋งค๊ฐœ๋ณ€์ˆ˜)์˜ ํƒ€์ž… ์‚ญ์ œ ๊ฐ€๋Šฅ
var multiply2: (Int, Int) -> Int = { (a, b) -> Int in
    return a * b
}

// return ํ‚ค์›Œ๋“œ ์‚ญ์ œ๊ฐ€๋Šฅ + ํŒŒ๋ผ๋ฏธํ„ฐ(๋งค๊ฐœ๋ณ€์ˆ˜) ์‚ญ์ œ ๊ฐ€๋Šฅ
var multiply3: (Int, Int) -> Int = {$0 * $1}

$0, $1 ์€ ๊ฐ๊ฐ a,b๋ฅผ ์˜๋ฏธํ•˜๋ฉฐ ์ด๋ ‡๊ฒŒ ํ‘œํ˜„ํ•˜๋Š” ๊ฒƒ์„ shorhand argument๋ผ๊ณ ํ•œ๋‹ค.

 

ํ•จ์ˆ˜๊ฐ€ ํด๋กœ์ €๋ฅผ argument๋กœ ๋ฐ›๋Š”์ƒํ™ฉ - ๋‹ค์–‘ํ•œ ํ™œ์šฉ์ด ๊ฐ€๋Šฅ

func operateTwoNum(a: Int, b: Int, operation: (Int, Int) -> Int) -> Int {
    let result = operation(a,b)
    return result
}

var add: (Int, Int) -> Int = { a,b in
    return a + b
}

operateTwoNum(a: 4, b: 9, operation: multiply)  // multyply๋ฅผ ๋„ฃ์œผ๋ฉด ๊ณฑํ•˜๊ธฐ
operateTwoNum(a: 4, b: 9, operation: add) // add ํด๋กœ์ €๋ฅผ ๋„ฃ์–ด ๋”ํ•˜๊ธฐ
operateTwoNum(a: 4, b: 9 ){ a, b in // ์•„๊ทœ๋จผํŠธ ๋ธ”๋Ÿญ์— ํด๋กœ์ €๋ฅผ ์ง์ ‘ ๊ตฌํ˜„ํ•ด๋„ ๋œ๋‹ค.
    return a - b
}

 

typealias์™€ ๊ฐ™์ด ์‚ฌ์šฉํ•˜๋Š” ํด๋กœ์ €

let c = {(str:String)->String in
    return "Hello \(str)"
}

typealias MyType = (String) -> String

func perform(closure: MyType){
    print(closure("iOS"))
}

perform(closure: c) // closure์— c๋ฅผ ์ „๋‹ฌ

 

fucking closure syntax

Url์€ ํ™”๋‚˜์žˆ์ง€๋งŒ ๊ฐ€๋ณด๋ฉด ๋‹ค์–‘ํ•œ ํด๋กœ์ € ํ˜•ํƒœ๊ฐ€ ๋‚˜์˜จ๋‹ค.

https://fuckingclosuresyntax.com/

 

How Do I Declare a Closure in Swift?

As a variable: var closureName: (ParameterTypes) -> ReturnType = { ... } As an optional variable: var closureName: ((ParameterTypes) -> ReturnType)? As a type alias: typealias ClosureType = (ParameterTypes) -> ReturnType As a constant: let closureName: Clo

fuckingclosuresyntax.com

 

์ฐธ๊ณ ์ž๋ฃŒ

https://docs.swift.org/swift-book/LanguageGuide/Closures.html#ID103

Contents

ํฌ์ŠคํŒ… ์ฃผ์†Œ๋ฅผ ๋ณต์‚ฌํ–ˆ์Šต๋‹ˆ๋‹ค

์ด ๊ธ€์ด ๋„์›€์ด ๋˜์—ˆ๋‹ค๋ฉด ๊ณต๊ฐ ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค.