closure(클로저)란?
코드에서 전달 및 사용할 수 있는 독립 기능 블록이며, 일급 객체의 열할을 할 수 있음
일급객체란?
전달 인자로 보낼 수 있고, 변수/상수 등으로 저장하거나 전달할 수 있으며, 함수의 반환 값이 될 수 있다.
클로저 표현식
{ (매개 변수) -> 리턴 타입 in // 클로저 헤드
실행 구문 // 클로저 바디
}
클로저 헤드와 클로저 바디를 구분하기 위해 in 키워드를 사용한다
매개 변수와 리턴이 없는 클로저 예시
let hello = { () -> () in
print("hello")
}
hello()
매개 변수와 리턴이 없다면 공백으로 두고 print를 호출하는 클로저이다. 호출하는 방법은 함수와 동일하게 변수뒤에 소괄호를 붙여 호출할 수 있다.
매개 변수와 리턴이 있는 클로저 예시
let hello2 = { (name: String) -> String in
return "Hello, \(name)"
}
hello2("woo")
클로저를 호출할 때는 파라미터 이름을 적지 않아야한다.
클로저를 함수의 매개 변수로 전달하는 예시
func doSomething(closure: () -> ()) {
closure()
}
doSomething ( closure: { () -> () in
print("hello")
})
함수의 매개 변수를 클로저로 받도록 하고 함수를 호출할 때 매개 변수에 클로저를 작성하면 된다.
클로저를 반환하는 함수 예시
func doSomething2() -> () -> () {
return { () -> () in
print("hello4")
}
}
doSomething2()()
후행 클로저
클로저를 여러개 사용하거나 보기 불편할 정도로 길어질 때 후행 클로저를 사용하여 코드를 더 짧게 작성할 수 있다.
예시
doSomething ( closure: { () -> () in
print("hello")
})
doSomething() {
print("hello2")
}
doSomething {
print("hello3")
}
보통 두번째 방법으로 사용하지만 매개 변수가 하나인 경우에는 세번째 방법처럼 소괄호도 생략 가능하다. 매개 변수가 여러개인 함수를 호출할 때는 마지막 매개 변수의 클로저만 후행 클로저가 가능하다.
문법 경량화
func doSomething3(closure: (Int, Int, Int) -> Int) {
closure(1,2,3)
}
doSomething3(closure: { (a, b, c) in
return a+b+c
})
doSomething3(closure: {
return $0+$1+$2
})
doSomething3(closure: {
$0+$1+$2
})
doSomething3() {
$0+$1+$2
}
doSomething3 {
$0+$1+$2
}
위와 같이 다양한 경량 문법을 사용할 수 있지만 너무 짧게만 코드를 작성하다보면 다른 사람이 이해하기 어려울 수 있으니 주의해서 사용해야겠다.