클로저
는 보통은 익명함수
로 인식되지만, 정확하게는 func
함수들도 모두 클로저
이다. ( 함수
도 클로저
다 )
클로저
는 크게 2가지로 나뉜다.
ㄴ Named Closure
ㄴ Unnamed Closure
func doSomething(){
print("Something")
}
let closure = {
() -> () in
print("Something")
}
이지만 인자도 없고, 반환형도 없으니 윗줄을 모두 날리면
let shortClosure = {
print("Something")
}
이렇게 간단해질 수 있다.
closure()
이렇게 실행할 수 있다.즉시실행함수 IIFE
처럼 클로저를 선언과 동시에 바로 호출하고 싶다면(
클로저 본문
)()
을 하면 된다. 반환형도 없고 인자도 없다면
({print("hello")})()
와 같이 될 수도 있다.
클로저
에서의 값 캡쳐클로저
는 내부 함수와 내부함수에 영향을 미치는 주변 환경을 모두 포함한 객체이다.func doSomething(){
var message = "Hello, nice to meet you!"
let closure = {
() -> () in
print( message );
}
}
클로저에서는 클로저에 영향을 미치는 외부변수도 사용할 수 있다. 이를 값의 캡쳐
라고 한다.
클로저
의 값 캡쳐방식
클로저
는 값을 캡쳐할 때 값타입
참조타입
에 관계 없이 참조 캡쳐
한다. 예시코드를 살펴보면
func doSomething(){
var num : Int = 0
print("\(num)")
let closure = {
() -> () in
print("\(num)")
}
num = 20
print("\(num)")
}
만약에 클로저
에서의 캡쳐
가 값 캡쳐
였다면, 출력은 0, 0, 20 이 되어야 하는게 맞겠지만 실제 출력은 0, 20, 20 이다.
이는 클로저
가 참조 캡쳐
를 하기 때문이다.
*만약에 참조 캡쳐가 하기 싫고, 값 캡쳐를 하고 싶다면 이렇게 하면 된다. 자세한 설명은 하단에
let closure = {
[num] in
print("\(num)")
}
이렇게 하면 되고 이렇게 되면 값 캡쳐
기 때문에 출력은 0, 0, 20 이 된다.
클로저
의 캡쳐리스트
let closure = { [num1, num2] in
클로저의 시작인 {
바로 옆에 []
을 이용해서 캡쳐할 멤버
를 나열한다.
in
키워드는 꼭 들어가야 한다.