Β μ€μννΈλ κ°μ²΄μ§ν₯ μΈμ΄μ΄μ λμμ ν¨μν μΈμ΄μ΄λ€. ν¨μν μΈμ΄λ₯Ό νμ΅νκ² λλ©΄ λ°λμ μΌκΈ κ°μ²΄(First-Class Object)λΌλ μ©μ΄λ₯Ό μ νκ² λλ€.
Β κ°μ²΄κ° λ€μ 쑰건μ λ§μ‘±νλ κ²½μ° μ΄ κ°μ²΄λ₯Ό μΌκΈ κ°μ²΄λ‘ κ°μ£Όνλ€.
- κ°μ²΄κ° λ°νμμλ μμ±μ΄ κ°λ₯ν΄μΌ νλ€.
- μΈμκ°μΌλ‘ κ°μ²΄λ₯Ό μ λ¬ν μ μμ΄μΌ νλ€.
- λ°νκ°μΌλ‘ κ°μ²΄λ₯Ό μ¬μ©ν μ μμ΄μΌ νλ€.
- λ³μλ λ°μ΄ν° ꡬ쑰 μμ μ μ₯ν μ μμ΄μΌ νλ€.
- ν λΉμ μ¬μ©λ μ΄λ¦κ³Ό κ΄κ³μμ΄ κ³ μ ν ꡬλ³μ΄ κ°λ₯ν΄μΌ νλ€.
Β ν¨μκ° μ΄λ° 쑰건μ λ§μ‘±νλ©΄ μΌκΈν¨μ(First-Class Function) μ΄λΌκ³ νκ³ ν¨μν μΈμ΄λ‘ λΆλ₯νκ³ , ν¨μκ° μΌκΈ κ°μ²΄λ‘ λμ°λ°λλ€.
Β 1. λ³μλ μμμ ν¨μλ₯Ό λμ ν μ μμ
func foo(base: Int) -> String {
return "κ²°κ³Όκ°μ \(base + 1)"
}
let fn1 = foo(base: 5)
// κ²°κ³Όκ°μ 6
Β μ μ½λλ λ¨μν ν¨μμ κ²°κ³Όκ°μ λμ νκ³ μλ€. κ·Έλ¬λ 'λ³μλ μμμ ν¨μλ₯Ό λμ νλ€'λ ν¨μ μ체λ₯Ό λμ νλ κ²μ΄λ€. ν¨μ μ체λ₯Ό λ³μμ ν λΉνλ©΄ λ³μλ ν¨μμ²λΌ μΈμκ°μ λ°μ μ€νμ΄ κ°λ₯νκ³ , κ°μ λ°νν μ μλ€.
let fn2 = foo
fn2(5)
// κ²°κ³Όκ°μ 6
Β μμ fn2μ foo ν¨μ μ체λ₯Ό λμ νκ³ fn2μ ν¨μ νΈμΆ μ°μ°μμΈ( )μ μΈμκ°5λ₯Ό λ£μ΄ νΈμΆν μλ μκ³ κ²°κ³Όκ°μ λ°μ μλ μλ€. fn2λ ν¨μμ΄λ€.
Β λν ν¨μλ₯Ό λμ νκΈ° μν΄ νμ (Type)μ λν΄μλ μμμΌνλ€. ν¨μ νμ μ ν¨μμ ννμ λ°λΌ μ μ μμ λ§νΌ λμν ꡬ쑰λ₯Ό κ°λλ€. λ³μμ μ μλ₯Ό λμ νλ©΄ Int νμ μ΄, λ¬Έμμ΄μ λμ νλ©΄ String νμ μ΄ λλ κ²μ²λΌ, λ³μμ ν¨μλ₯Ό λμ νλ©΄ ν¨μ νμ μ΄ λλ κ²μ΄λ€.
func boo(age: Int) -> String {
return "\(age)"
}
//μ ν¨μλ₯Ό ν¨μ νμ
μΌλ‘ νν
(Int) -> String
// μμ ν¨μλ₯Ό μμμ ν λΉνμ λ νμ
μ΄λ
Έν
μ΄μ
μ ν¬ν¨ν ν λΉ κ΅¬λ¬Έ
let fn: (Int) -> String = boo
// λ κ°μ μΈμκ°μ λ°λ ν¨μ
func boo(age: Int, name: String) -> String {
return "\(name)"μ λμ΄λ \(age)"
}
// μ ν¨μλ₯Ό ν¨μ νμ
μΌλ‘ μμ±
(Int, String) -> String
// μ νν μλ³μλ₯Ό μ¬μ©ν κ²½μ°
let s: (Int, String) -> String = boo(age:name:)
βοΈκ° μ€μβοΈ
func boo(age: Int) -> String {
return "\(age)"
}
func boo(age: Int, name: String) -> String {
return "\(name)"μ λμ΄λ \(age)"
}
let t = boo(X) // μ€λ₯
μ΄λ° κ²½μ° μ΄λ ν¨μλ₯Ό κ°λ₯΄ν€λμ§ μ ννκ² νλ¨ν μ μμΌλ―λ‘ μ€λ₯κ° λλ€.
// ν΄κ²° λ°©λ² 1) νμ
μ΄λ
Έν
μ΄μ
μ ν΅ν΄ μ
λ ₯λ°μ ν¨μμ νμ
μ μ§μ
let t1: (Int, String) -> String = boo
// ν΄κ²° λ°©λ² 2) ν¨μμ μλ³κ°μ ν΅ν΄ μ
λ ₯λ°μ μ νν ν¨μλ₯Ό μ§μ
let t2 = boo(age:name:)
Β νμ μ΄λ Έν μ΄μ μ μ¬μ©νλ κ²½μ°μλ μ λ ₯λ°μ κ°μ νμ μ΄ λͺ ννκΈ° λλ¬Έμ, boo κ° κ°λ₯΄ν€λ ν¨μκ° λ€μ λΆνμ€νλλΌλ μ»΄νμΌλ¬κ° μ°Ύμμ λμ ν μ μλ€. μλ³κ°μ ν΅ν΄ μ§μ νλ κ²½μ°μλ μ νν ν¨μλ₯Ό μ°Ύμ λμ ν μ μκΈ° λλ¬Έμ λ¬Έμ κ° λμ§ μλλ€.
// μΈμκ°μ΄ μλ ν¨μμΈ κ²½μ°
func foo() -> String {
return "Empty Values"
}
// μΈμκ°μ΄ μλ κ²½μ° ν¨μ νμ
() -> String
// λ°νκ°μ΄ μλ κ²½μ°
func boo(base: Int) {
print("param = \(base)")
}
// λ°νκ°μ΄ μλ κ²½μ° ν¨μ νμ
(Int) -> ()
(Int) -> Void // μ΄λ κ²λ κ°λ₯
// μΈμκ°, λ°νκ°μ΄ λͺ¨λ μλ κ²½μ°
func too() {
print("empty values")
}
// μΈμκ°, λ°νκ°μ΄ λͺ¨λ μλ κ²½μ° ν¨μνμ
() -> ()
() -> Void
Β 2. ν¨μμ λ°ν νμ μΌλ‘ ν¨μλ₯Ό μ¬μ©ν μ μμ
Β μΌκΈ ν¨μλ μ€ν κ²°κ³Όλ‘ μ μ, μ€μ, λ¬Έμμ΄ λ±μ κΈ°λ³Έ μλ£νμ΄λ ν΄λμ€, ꡬ쑰체 λ±μ κ°μ²΄λ₯Ό λ°νν μ μμ λΏ μλλΌ ν¨μ μ체λ₯Ό λ°νν μλ μλ€.
func desc() -> String {
return "this is desc()"
}
func pass() -> () -> String {
return desc
}
let p = pass()
p() // "this is desc()"
Β μ μ½λμμ desc λΌλ λ¬Έμμ΄μ λ°ννλ ν¨μκ° μκ³ , pass ν¨μκ° desc ν¨μλ₯Ό λ°ννκΈ° λλ¬Έμ () -> String μΌλ‘ ν¨μμ νμ ννμ νκ³ μλ€. μ΄ ν¨μ νμ μ ννμ΄ pass ν¨μμ λ°ν νμ μΌλ‘ μ¬μ©λκ³ μλ κ²μ΄λ€.
Β μ΄μ΄μ μμ pλ pass ν¨μμ μ€ν κ²°κ³Όκ°μ ν λΉλ°κ³ μλ€. pass ν¨μμ μ€ν κ²°κ³Όλ desc ν¨μμ΄λ―λ‘ μμ pμλ desc ν¨μκ° ν λΉλλ€. μ΄μ μμ pλ desc ν¨μλ λ§μ°¬κ°μ§μ΄λ€. pμ ν¨μ νΈμΆ μ°μ°μ( ) λ₯Ό λΆμ¬ μ€ννλ©΄ desc ν¨μκ° μ€νλλ κ²μ΄λ€.
// ν¨μμ λ°ννμ
μΌλ‘ ν¨μλ₯Ό μ¬μ©νλ μμ
func plus(a: Int, b: Int) -> Int {
return a + b
}
func plus(a: Int, b: Int) -> Int {
return a - b
}
func plus(a: Int, b: Int) -> Int {
return a * b
}
func plus(a: Int, b: Int) -> Int {
guard b !0 = else {
return 0
}
return a / b
}
func calc(_ operand: String) -> (Int, Int) -> Int {
switch operand {
case "+" :
return plus
case "-" :
return minus
case "*" :
return time
case "/" :
return divide
default :
return plus
}
}
let res = calc("+")
res(3,4) // plus(3, 4) = 7
calc("-")(10, 10) // 0
Β μ΄μ²λΌ ν¨μμ μ€ν κ²°κ³Όλ‘ λ€λ₯Έ ν¨μλ₯Ό λ°νν μ μλ κ²μ΄ μΌκΈ ν¨μμ νΉμ±μ΄λ€.
Β 3. ν¨μμ μΈμκ°μΌλ‘ ν¨μλ₯Ό μ¬μ©ν μ μμ
Β μΌκΈ ν¨μλ λ°νκ°μΌλ‘ ν¨μλ₯Ό μ¬μ©ν μ μμ λΏ μλλΌ λ€λ₯Έ ν¨μμ μΈμκ°μΌλ‘ ν¨μλ₯Ό μ λ¬ν μ μλ νΉμ±λ μλ€. μλ°μ€ν¬λ¦½νΈμ λ§μ°¬κ°μ§λ‘ μ€μννΈμλ μ½λ²‘ν¨μ(CallBack Function)κ° μλλ° μ½λ²‘ ν¨μλ νΉμ ꡬ문μ μ€νμ΄ λλλ©΄ μμ€ν μ΄ νΈμΆνλλ‘ μ²λ¦¬λ ν¨μλ‘, μ½λ²‘ ν¨μλ₯Ό λ±λ‘νλ€λ κ²μ μ€ννκ³ μ νλ ꡬ문μ λ΄μ ν¨μλ₯Ό μΈμκ°μΌλ‘ λ£λ κ²μ μλ―Ένλ€. μ΄ λ μ¬μ©λλ κ°λ μ΄ 'ν¨μλ₯Ό μΈμκ°μΌλ‘ μ¬μ©ν μ μλ€' μ΄λ€.
//ν¨μλ₯Ό μΈμκ°μΌλ‘ μ λ¬νλ μμ
func incr(param: Int) -> Int {
return param + 1
}
//맀μ§μ½λλΌκ³ λ ν¨
func broker(base: Int, function fn: (Int) -> Int) -> Int {
return fn(base)
}
broker(base: 3, function: incr) // 4
Β μ€μννΈμμ ν¨μλ μ€μ²©νμ¬ μμ±ν μ μλ€. ν¨μ λ΄μ λ€λ₯Έ ν¨μλ₯Ό μμ±ν΄μ μ¬μ©ν μ μλ κ²μ΄λ€. μ€μ²©ν¨μ(Nested Function)μ ν¨μ λ΄μ μμ±λ ν¨μμΈ λ΄λΆ ν¨μ(InnerFunction)μ λ΄λΆ ν¨μλ₯Ό ν¬ν¨νλ λ°κΉ₯μͺ½ ν¨μμΈ μΈλΆ ν¨μ(Outer Function)μΌλ‘ ꡬλΆν μ μλ€.
Β ν¨μλ₯Ό μ€μ²©ν΄μ μ μνλ©΄ λ΄λΆ ν¨μλ μΈλΆν¨μκ° μ€νλλ μκ° μμ±λκ³ , μ’ λ£λλ μκ° μλ©Ένλ€. μΈλΆ ν¨μλ νλ‘κ·Έλ¨μ΄ μ€νλ λ μμ±λκ³ νλ‘κ·Έλ¨μ΄ μ’ λ£λ λ μλ©Ένμ§λ§, λ΄λΆ ν¨μλ μΈλΆ ν¨μμ μ€νκ³Ό μ’ λ£ μ¬μ΄μμ μκ²Όλ€κ° μ¬λΌμ§λ€. μ΄κ²μ΄ λ΄λΆ ν¨μμ μλͺ μ£ΌκΈ°(Life Cycle)μ΄λ€.
Β λ΄λΆ ν¨μλ μΌλ°μ μΌλ‘ μΈλΆ ν¨μλ₯Ό κ±°μΉμ§ μμΌλ©΄ μ κ·Όν μ μλ€ μ΄ λλ¬Έμ λ΄λΆ ν¨μλ μΈλΆμ μ½λλ‘λΆν° μ°¨λ¨λλ κ²°κ³Όλ₯Ό κ°μ Έμ€λλ° μ΄λ₯Ό ν¨μμ μλμ±μ΄λΌκ³ νλ©° μ€μ²©λ ν¨μλ₯Ό μ¬μ©νλ©΄ ν¨μμ μλμ±μ λμΌ μ μλ€.
// μΈλΆ ν¨μ
func outer(base: Int) -> String {
// λ΄λΆ ν¨μ
func inner(inc: Int) -> String {
return "\(int)λ₯Ό λ°ν"
}
let result = inner(inc: base +1)
return result
}
outer(base: 3) // 4λ₯Ό λ°ν
Β μ μ½λμμ innerλΌλ ν¨μλ μΈλΆμμ μ°Έμ‘°ν μ μμΌλ©° μ€μ§ outer ν¨μ λ΄λΆμμλ§ μ°Έμ‘°ν μ μλ€. inner ν¨μλ μΈλΆλ‘λΆν° μλλμ΄ μλ κ²μ΄λ€.
Β λ΄λΆν¨μμ μλͺ μ£ΌκΈ°μ λν΄ μμλ³Έλ€λ©΄, μΌλ°μ μΌλ‘ ν¨μλ μμ μ μ°Έμ‘°νλ κ³³μ΄ μμΌλ©΄ μμ±λμλ€κ° μ°Έμ‘°νλ κ³³μ΄ μ¬λΌμ§λ©΄ μ κ±°λλ μλͺ μ£ΌκΈ°λ₯Ό κ°λλ€. ν¨μμ μλͺ μ£ΌκΈ°λ μ°Έμ‘° μΉ΄μ΄νΈμ κ΄λ ¨λμ΄ μλ€. μ°Έμ‘° μΉ΄μ΄νΈκ° 0μμ 1μ΄ λλ μκ° μμ±λμ΄ 1 μ΄μμΈ λμ μ μ§λλ€κ°, 0μ΄ λλ©΄ μλ©Ένλ κ³Όμ μ λ°λ³΅νλ κ²μ΄λ€.
μ€μβοΈ
func outer(param: Int) -> (Int) -> String {
// λ΄λΆ ν¨μ
func inner(inc: Int) -> String {
return "\(inc)λ₯Ό 리ν΄"
}
return inner
}
let fn1 = outer(param: 3) // outer()κ° μ€νλκ³ , κ·Έ κ²°κ³Όλ‘ innerκ° λμ
λ¨
let fn2 = fn1(30) // inner(inc: 30)κ³Ό λμΌ
Β μ μ½λμμ μΈλΆν¨μ outerλ let fn1 = outer(param: 3) ꡬ문μ μ€ν μ’ λ£μ ν¨κ» μ κ±°λμ§λ§ λ΄λΆ ν¨μμΈ innerκ° κ²°κ³Όκ°μΌλ‘ λ°νλμ΄ μμ fn1μ μ°Έμ‘°λμμΌλ―λ‘ μ°Έμ‘° μΉ΄μ΄νΈκ° μ‘΄μ¬νκ³ , μΈλΆν¨μμΈ outerκ° μ£½μλλΌλ λ΄λΆν¨μμΈ innerλ μ΄μμλ κ²μ΄λ€.
μ€μβοΈ
func basic(param: Int) -> (Int) -> Int {
let value = param + 20
// λ΄λΆ ν¨μ
func append(add: Int)> Int {
return value + add
}
return append
}
let result = basic(param: 10)
result(10) // μ€λ₯κ° μλκ³ κ²°κ³Ό: 40 ?
Β μ μ½λμμ valueμ μ£Όλͺ©ν΄λ³΄μ!! ν¨μ λ΄μμ μ μλ κ°λ€μ ν¨μκ° μ’ λ£λκΈ° μ§μ κΉμ§λ§ μ‘΄μ¬νλ―λ‘ value μμκ° let result = basic(param: 10) μ΄ κ΅¬λ¬Έμ΄ μ’ λ£λκΈ° μ§μ κΉμ§λ§ μ‘΄μ¬ν΄μΌ νλ€. λ°λΌμ μ€λ₯κ° λ°μν κ²μ΄λΌκ³ μμνμ§λ§ 40μ΄λΌλ κ²°κ³Όκ° λμλ€. μ΄λ append ν¨μκ° ν΄λ‘μ (Closure)λ₯Ό κ°κΈ° λλ¬Έμ΄λ€. ν΄λ‘μ λ λ΄λΆ ν¨μμ λ΄λΆ ν¨μμ μν₯μ λ―ΈμΉλ μ£Όλ³ νκ²½(Context)μ λͺ¨λ ν¬ν¨ν κ°μ²΄μ΄λ€. μ¬κΈ°μ μ£Όλ³ νκ²½μ΄λ λ΄λΆ ν¨μμμ μ°Έμ‘°νλ λͺ¨λ μΈλΆ λ³μλ μμ κ°, κ·Έλ¦¬κ³ λ΄λΆ ν¨μμμ μ°Έμ‘°νλ λ€λ₯Έ κ°μ²΄κΉμ§λ₯Ό λ§νλ€.
Β ν΄λ‘μ λ κ°μ²΄μμ²΄κ° μλ κ°μ ν¬ν¨νλ κ²μ΄λ€. λ°λΌμ let result = basic(param: 10)μ΄ μ€νλ¬μ λ resultμ μ μ₯λλ ν΄λ‘μ λ λ€μκ³Ό κ°μ ννλ‘ μ μ₯λλ κ²μ΄λ€.
func append(add: Int)> Int {
return 30 + add
}
Β μμμ μ΄μΌκΈ°νλ ν΄λ‘μ λ μννΈμ¨μ΄ μν€ν μ²μ μΈ κ°λ μ΄μκ³ μ€μ λ‘ μ€μννΈμμμ ν΄λ‘μ λ μΌνμ© ν¨μλ₯Ό μμ±ν μ μλ ꡬ문μ΄λ€. μ΅λͺ ν¨μ(Anonymous) ν¨μλΌκ³ λΆλ₯΄κΈ°λ νλ€.
Β μ€μννΈμμ ν΄λ‘μ λΌκ³ λΆλ₯΄λ κ°μ²΄λ λ€μ μΈ κ°μ§ κ²½μ° μ€ νλμ΄λ€.
- μ μ ν¨μ: μ΄λ¦μ΄ μκ³ . μ£Όλ³ νκ²½μμ μΊ‘μ²ν μ΄λ€ κ°λ μλ ν΄λ‘μ
- μ€μ²© ν¨μ: μ΄λ¦μ΄ μκ³ μμ μ λλ¬μΌ ν¨μλ‘λΆν° κ°μ μΊ‘μ²ν μ μλ ν΄λ‘μ
- ν΄λ‘μ ννμ μ΄λ¦μ΄ μκ³ μ£Όλ³ νκ²½μΌλ‘λΆν° κ°μ μΊ‘μ²ν μ μλ κ²½λ λ¬Έλ²μΌλ‘ μμ±λ ν΄λ‘μ
{ (맀κ°λ³μ) -> λ°ν νμ
in
μ€νν ꡬ문
}
{ () -> () in
print("ν΄λ‘μ μ€ν")
}
// μμ±λ ν΄λ‘μ ννμμ κ·Έμμ²΄λ‘ ν¨μλΌκ³ ν μ μμ
let f = { () -> Void in
print("ν΄λ‘μ μ€ν")
}
f() // ν΄λ‘μ μ€ν
// ν΄λ‘μ ννμμ ν λΉλ°μ μμ fλ§μ μλ΅νκ³ μΆμ λ μ΄λ κ² μμ±ν΄λ λ¨
({ () -> Void in
print("ν΄λ‘μ μ€ν")
})() // ν΄λ‘μ μ€ν
var val = [1,9,5,7,3,2]
func order(s1: Int, s2: Int) -> Bool {
if s1 > s2 {
return true
} else {
return false
}
}
val.sort(by: order)
// ν΄λ‘μ ννμμΌλ‘
{
(s1: Int, s2: Int) -> Bool {
if s1 > s2 {
return true
} else {
return false
}
}
val.sorted(by: {
(s1: Int, s2: Int) -> Bool in
if s1 > s2{
return true
}else {
return false
}
})
//κ°κ²°ν
val.sort(by: {(s1: Int, s2: Int) -> Bool in return s1 > s2})
val.sort(by: {(s1:Int, s2: Int) in return s1 > s2})
val.sort(by: {s1, s2 in return s1 > s2})
val.sort(by: { $0 > $1})
Β νΈλ μΌλ§ ν΄λ‘μ λ ν¨μμ λ§μ§λ§ μΈμκ°μ΄ ν΄λ‘μ μΌ λ, μ΄λ₯Ό μΈμκ° νμμΌλ‘ μμ±νλ λμ ν¨μμ λ€μ 꼬리μ²λΌ λΆμΌ μ μλ λ¬Έλ²μ μλ―Ένλ€.
//κ·Έλ₯ ν΄λ‘μ
value.sort(by: {(s1, s2) in
return s1 > s2
})
//νΈλ μΌλ§ ν΄λ‘μ
value.sort() { (s1, s2) in
return s1 > s2
}
Β μμμ κ·Έλ₯ ν΄λ‘μ μ νΈλ μΌλ§ ν΄λ‘μ λ λ¬λΌ 보μ΄λ κ²μ΄ κ±°μ μλ€. κ·Έλ¬λ μΈμκ°μΌλ‘ μ¬μ©λλ ν΄λ‘μ κ° ν΅μ§Έλ‘ λ°κΉ₯μΌλ‘ λΉ μ Έλμ¨ λ€μ, sort( ) λ©μλμ λ€μͺ½μ λ¬λΌ λΆμ κ²μ λ³Ό μ μλ€.
Β μ΄λ κ² κ΄νΈ νλ μ°¨μ΄ μ΄μ§λ§ μ΄κ³ λ«λ λ²μκ° λμ΄μ§λ©΄ ν·κ°λ¦΄μλ μλ€. λν λ°μ νΈλ μΌλ§ ν΄λ‘μ λ μ°λ¦¬κ° μμ£Ό μ¬μ©νλ if λ¬Έκ³Ό μ½λμ κ΄νΈ ννκ° λΉμ·νκΈ° λλ¬Έμ ν¨μ¬ μ΅μνλ€λ μ₯μ μ΄ μλ€.
value.sort { (s1, s2) in
return s1 > s2
}
Β μ μ½λμ κ°μ΄ μΈμκ°μ΄ νλμΌ κ²½μ° sort λ©μλ λ€μ κ΄νΈ() λν μλ΅ν μ μλ€. κ·Έλ¬λ μΈμκ°μ΄ μ¬λ¬κ°λΌλ©΄ 무μμ κ΄νΈλ₯Ό μλ΅ν΄μλ μλλ€.
Β ν΄λ‘μ λ₯Ό ν¨μλ λ©μλμ μΈμκ°μΌλ‘ μ¬μ©ν λμλ μ©λμ λ°λΌ @escapingκ³Ό @autoclosure μμ±μ λΆμ¬ν μ μλ€.
@escaping
Β @escaping μμ±μ μΈμκ°μΌλ‘ μ λ¬λ ν΄λ‘μ λ₯Ό μ μ₯ν΄ λμλ€κ°, λμ€μ λ€λ₯Έ κ³³μμλ μ€νν μ μλλ‘ νμ©ν΄μ£Όλ μμ±μ΄λ€.
func callback(fn: () -> Void) {
fn()
}
callback {
print("Closure μ€ν")
}
// Closure μ€ν
Β μ μλ ν¨μ callback(fn:)μ 맀κ°λ³μλ₯Ό ν΅ν΄ μ λ¬λ ν΄λ‘μ λ₯Ό ν¨μ λ΄λΆμμ μ€ννλ μν μ νλ€.
func callback(fn: () -> Void) {
let f = fn // ν΄λ‘μ λ₯Ό μμ fμ λμ
f() // λμ
λ ν΄λ‘μ λ₯Ό μ€ν
}
//μ€λ₯: Non-escaping parameter 'fn' may only be called
Β κ·Έλ¬λ λ€μκ³Ό κ°μ΄ μ½λλ₯Ό λ°κΎΈλ©΄ Non-escaping νλΌλ―Έν°μΈ 'fn'μ μ€μ§ μ§μ νΈμΆνλ κ²λ§ κ°λ₯νλ€κ³ μ€λ₯κ° λλ€.
κΈ°λ³Έμ μΌλ‘ μ€μννΈμμλ ν¨μμ μΈμκ°μΌλ‘ μ λ¬λ ν΄λ‘μ (μ΅λͺ
ν¨μ)λ κΈ°λ³Έμ μΌλ‘ νμΆλΆκ°(non-escape)μ μ±κ²©μ κ°μ§λ€. μ΄λ ν΄λΉ ν΄λ‘μ λ₯Ό ν¨μλ΄μμ, μ§μ μ€νμ μν΄μλ§ μ¬μ©ν΄μΌ νλ κ²μ μλ―Ένλ©° ν¨μλ΄λΆλΌκ³ νλλΌλ λ³μλ μμμ λμ
ν μ μλ€.
Β λ³μλ μμμ λμ νλ κ²μ νμ©νλ€λ©΄ λ΄λΆ ν¨μλ₯Ό ν΅ν μΊ‘μ²(Capture) κΈ°λ₯μ μ΄μ©νμ¬ ν΄λ‘μ κ° ν¨μ λ°κΉ₯μΌλ‘ νμΆν μ μκΈ° λλ¬Έμ΄λ€. μ¬κΈ°μ λ§νλ νμΆμ΄λ, ν¨μ λ΄λΆ λ²μλ₯Ό λ²μ΄λμ μ€νλλ κ²μ μλ―Ένλ€.
Β λν μΈμκ°μΌλ‘ μ λ¬λ ν΄λ‘μ λ μ€μ²©λ λ΄λΆ ν¨μμμλ μ¬μ©ν μ μλ€. λ΄λΆ ν¨μμμ μ¬μ©ν μ μλλ‘ νμ©ν κ²½μ°, μ΄ μμ 컨ν μ€νΈ(Context)μ μΊ‘μ²λ₯Ό ν΅ν΄ νμΆλ μ μκΈ° λλ¬Έμ΄λ€.
func callback(fn: () -> Void) {
func innerCallback() {
fn()
}
}
Β λ°λΌμ μ μ½λλ₯Ό μ€ννλ©΄ μ€λ₯κ° λλ€.
νμ§λ§ μ½λλ₯Ό μμ±νλ€ λ³΄λ©΄ ν΄λ‘μ λ₯Ό λ³μλ μμμ λμ
νκ±°λ μ€μ²© ν¨μ λ΄λΆμμ μ¬μ©ν΄μΌ ν κ²½μ°κ° μλ€. μ΄λ μ¬μ©νλ κ²μ΄ @escaping μμ±μ΄λ€.
func callback(fn: @escaping() -> Void) {
let f = fn // ν΄λ‘μ λ₯Ό μμ fμ λμ
f() // λμ
λ ν΄λ‘μ λ₯Ό μ€ν
}
callback {
print("Closure μ€ν")
}
// Closure μ€ν
Β μμμ μ€λ₯κ° λ¬λ ν¨μμΈλ° μ¬κΈ°μ 맀κ°λ³μ νμ μ μμ @escaping μμ±μ λΆμ¬ μ£Όλ μ€λ₯ μμ΄ μ μ λμνμλ€.
Β μ΄μ μ λ ₯λ ν΄λ‘μ λ λ³μλ μμμ μ μμ μΌλ‘ ν λΉλκ³ , μ€μ²©λ λ΄λΆ ν¨μμ μ¬μ©ν μ μκ³ , ν¨μ λ°κΉ₯μΌλ‘λ μ λ¬ν μ μλ€.
Β νμΆ κ°λ₯ν ν΄λ‘μ κ° λκ²μ΄λ€.
@autoclosure
Β @autoclosure μμ±μ μΈμκ°μΌλ‘ μ λ¬λ μΌλ° ꡬ문μ΄λ ν¨μ λ±μ ν΄λ‘μ λ‘ λν(Wrapping)νλ μν μ νλ€. μ½κ² λ§ν΄ μΌλ° ꡬ문μ μΈμκ°μΌλ‘ λ£λλΌλ μ»΄νμΌλ¬κ° μμμ ν΄λ‘μ λ‘ λ§λ€μ΄μ μ¬μ©νλ€λ κ²μ΄λ€.
func condition(stmt: () -> Bool) {
if stmt() == true {
print("κ²°κ³Όλ μ°Έμ
λλ€.")
} else {
print("κ²°κ³Όκ° κ±°μ§μ
λλ€.")
}
}
// μ€ν λ°©λ² 1: μΌλ° ꡬ문
condition(stmt: {
4 > 2
})
//μ€ν λ°©λ² 2: κ²½λν λ¬Έλ²
// κ²½λν λμ§ μμ ν΄λ‘μ μ 체 λ¬Έλ²
condition{ () -> Bool in
return (4 > 2)
}
// ν΄λ‘μ νμ
μ μΈ μλ΅
condition{
return (4 > 2)
}
// ν΄λ‘μ λ°νꡬ문 μλ΅
condition {
4 > 2
}
Β μμ½λμμ ν¨μκ° μκ³ κ·Έ ν¨μλ₯Ό νΈμΆνλ μ¬λ¬κ°μ§ λ°©λ²μ 보μλ€. ν΄λ‘μ μ κ²½λν λ¬Έλ²μ μ΄μ©νλ©΄μ λ μ§§κ³ κ°κ²°ν μ½λλ‘ ν¨μλ₯Ό νΈμΆν μ μμλ€.
Β @autoclosureλ‘ λ€μ λμκ°λ³΄λ©΄ μμμ ν¨μλ₯Ό νΈμΆν λ μνλ ꡬ문μ '{}'ννλ‘ κ°μΈ ν΄λ‘μ ννλ‘ λ§λ λ€μμ μΈμκ°μΌλ‘ λ§λ€μ΄ μ λ¬ν΄μΌ νλ€λ μ μ½μ΄ μλ€. νμ§λ§ @autoclosure() μμ±μ μ¬μ©νλ€λ©΄
func condition(stmt: @autoclosure() -> Bool) {
if stmt() == true {
print("κ²°κ³Όλ μ°Έμ
λλ€.")
} else {
print("κ²°κ³Όκ° κ±°μ§μ
λλ€.")
}
}
//ν¨μ μ€ν
condition(stmt: (4 > 2))
Β λ€μκ³Ό κ°μ΄ μΈμκ°μ '{}' ννκ° μλ '()' ννλ‘ μ¬μ©ν μ μλλ‘ ν΄μ€λ€. ν¨μ¬ μ΅μνκ³ μμ°μ€λ¬μ΄ ꡬ문μΌλ‘ λ§λ€μ΄μ£Όλ μ μ΄λ€.
Β λν @autoclosureμμ±μ μ¬μ©νλ©΄ 'μ§μ° μ€ν'μ ν μ μλ€.
//λΉ λ°°μ΄
var arrs = [String]()
func addVars(fn: @autoclosure () -> Void) {
// λ°°μ΄ μμλ₯Ό 3κ°κΉμ§ μΆκ°νμ¬ μ΄κΈ°ν
arrs = Array(repeating: "", count: 3)
// μΈμκ°μΌλ‘ μ λ¬λ ν΄λ‘μ μ€ν
fn()
}
// ꡬ문 1: μλ ꡬ문μ μ€λ₯κ° λ°μνλ€.
arrs.insert("KR", at: 1)
// ꡬ문 2: μ€λ₯ λ°μνμ§ μμ
addVars(fn: arrs.insert("KR", at: 1))
Β λΉ λ°°μ΄ arrsλ₯Ό μ μνμκ³ addVars(fn:) ν¨μ λ΄λΆμμλ μ΄ λ°°μ΄μ μ¬μ΄μ¦λ₯Ό 3μΌλ‘ νμ₯νκ³ λΉ κ°λ€λ‘ μ΄κΈ°ννλ€.
Β addVars(fn:) ν¨μκ° μ€νλκΈ° μ κΉμ§ μ΄ ν¨μμ μΈλ±μ€λ 0κΉμ§ λ°μ μμ΄ arrs.insert(at:) λ©μλλ μ€λ₯κ° λ°μνλ€.
Β κ·Έλ¬λ λμΌν ꡬ문μ addVars(fn:) ν¨μμ μΈμκ°μΌλ‘ λ£μΌλ©΄ μ€λ₯κ° λ°μνμ§ μλλ€. μλ ꡬ문μ μμ±νλ μκ°μ μ€νλμ§λ§, ν¨μ λ΄μ μμ±λ ꡬ문μ ν¨μκ° μ€νλκΈ° μ κΉμ§λ μ€νλμ§ μμ μ΄λ₯Ό μ§μ° μ€νμ΄λΌκ³ νλ€. @autoclosure μμ±μ΄ λΆμ¬λ μΈμκ°μ μΌλ° ꡬ문 ννμ΄μ§λ§ μ»΄νμΌλ¬μ μν΄ ν΄λ‘μ , ν¨μλ‘ κ°μΈμ§κΈ° λλ¬Έμ μμ κ°μ΄ μμ±ν΄λ addVars(fn:) ν¨μ μ€ν μ κΉμ§λ μ€νλμ§ μμΌλ©°, ν΄λΉ κ΅¬λ¬Έμ΄ μ€νλ λμλ μ΄λ―Έ λ°°μ΄μ μΈλ±μ€κ° λμ΄λ νμ΄λ―λ‘ μ€λ₯κ° λ°μνμ§ μλ κ²μ΄λ€.