클로저에는 두가지 종류가 있다.
우리가 여태 써왔던 이름이 있는 함수는
func doSomething() {
print("Named Closure")
}
이런 Named Closure이다. 하지만 이것을 클로저라고 부르지 않고 그냥 함수라고 불렀던 것이다.
그리고 이름을 붙이지 않고 사용하는 함수를
let closure = { print("Unnamed Closure") }
익명함수, 즉 Unnamed Closure 라고 부르는 것이다.
정리하자면
클로저는 Named Closure & Unnamed Closure 둘다 포함하지만,
보통 Unnamed Closure 를 말한다.
{ (Parameters) -> Return Type in
실행 구문
}
이렇게 표현식을 사용하는데, 익명 함수인 만큼 func 이란 키워드를 사용하지 않는다.
그리고 클로저는 Closure Head와 Closure Body로 이루어져 있는데
{ (Parameters) -> Return Type in
실행구문
}
// Closure Head : (Parameters) -> Return
// Closure Body : 실행구문
이 둘을 구분지어주는게 바로 in 이라는 키워드이다.
클로저는 익명이긴 하지만 함수이다.
따라서 Swift에서 1급 객체이기 때문에 상수에 클로저를 대입할 수 있다.
특히 Parameter 와 Return Type이 둘 다 없는 경우는 다음과 같이 사용함
let closure = { () -> () in
print("Closure")
}
Return Type 이 있어도, 없어도 생략 가능하고 Parameter 조차 생략 가능하다.
let driving = { (place: String) -> String in
return "저는 차를타고 \(place)에 가고 있습니다."
}
Parameter와 Return Type이 있는 경우는 이렇게 표시한다.
함수 때 배운 대로 Parameter의 place는 단독으로 쓰였으니,
Argument Label이자 Parameter Name이라고 생각할 수 있지만,
⭐ 클로저에선 Argument Label을 사용하지 않는다 ⭐
따라서, name은 Argument Label이 아니고, 오직 Parameter Name 이다.
클로저를 호출할 때는 Argument Label을 사용하지 않는다 !!
driving("회사") // 저는 차를 타고 회사에 가고 있습니다.
driving(place: "회사") // Error!
사용할 시 에러가 난다….!
클로저를 변수나 상수에 대입할 수 있다.
⇒ 클로저를 변수나 상수에 대입할 수 있고, 대입된 변수나 상수를 실행 시키는 것이 가능하다.
let closure = { () -> () in
print("Closure")
}
let closure2 = closure
func doSomething(closure: () -> ()) {
closure()
}
이런 식으로 함수를 파라미터로 전달받는 doSomething 이라는 함수가 있는데
파라미터로 함수를 넘겨줘도 되지만
doSomething(closure: { () -> () in
print("Hello!")
})
// 클로저로 작성된 부분 : { () -> () in print("Hello!") }
이렇게 클로저를 넘겨줘도 된다.
doSomething이란 함수에서 파라미터로 전달받은 함수를 실행시키면
작성한 클로저가 실행된다.
func doSomething() -> () -> () {
return { () -> () in
print("Hello JE!")
}
}
선언부는 기존 함수와 똑같지만 return할 때 실제 값을 함수가 아닌 클로저를 리턴 할 수 있다.
let closure = doSomething()
closure() // Hello JE!
또한 호출하는 곳에서 클로저를 받아서 이렇게 실행시킬 수 있다.
let closure = { () -> String in
return "Hello JE!"
}
closure() // Hello JE!
이런 식으로 클로저가 대입된 상수 closure를 호출 구문인 ()를 이용해서 실행시킬 수 있다.
({ () -> () in
print("Hello JE!")
})() // Hello JE!
클로저를 변수나 상수에 대입하지 않고 실행시키고 싶다면, (완벽한 일회성)
그땐 클로저를 ( ) 소괄호로 감싸고, 마지막에 호출 구문인 ()를 추가해주면 된다.