클로저
클로저(Closure)는 동작하는 코드의 단위로, 코드가 정의된 곳의 변수나 상수를 사용할 수 있다. Objective-C의 블록(block)에 해당한다.
클로저를 정의하는 형식은 다음과 같다.
{ ( PARAMETERS ) -> RETURN_TYPE in
// 코드
}
클로저를 사용하려면 함수 타입에 대해 익숙해져야 한다. 함수 타입은 파라미터의 타입과 개수, 반환 타입으로 구성된다.
파라미터가 없고 반환값이 없는 함수 타입은 () -> () 혹은 void -> void 이다.
// 함수 타입
(Int, Int) -> Int
// 함수 구현
func add(i : Int, j : Int) -> Int {
return i + j
}
다음은 배열을 정렬하는 sort메소드에 클로저를 사용하도록 작성한 코드이다.
var array = [2,3,1,4,5]
array.sort({ (a:Int, b: Int) -> Bool in
return a < b
})
// 타입 추론이 가능할 경우 클로저 파라미터의 타입 생략
array.sort({ (a,b) -> Bool in
return a < b
})
// 클로저 작성 코드가 결과를 반환하는 1줄 코드일 때 단축
array.sort({ a, b -> Bool in a < b })
// 클로저 파라미터를 $0, $1, $2로 참조할 수 있으므로 더 단축
array.sort( { $0 < $1 } )
Trailing 클로저
메소드 파라미터 중 클로저 타입이 마지막이면 클로저를 메소드 파라미터 외부에 작성할 수도 있다. 그리고 클로저가 단일 파라미터라면 괄호도 생략 가능하다.
array.sort { $0 < $1 }
다음은 배열의 각 원소의 클로저 동작 결과로 새로운 배열을 만드는 map 함수를 사용한 코드다.
let array2 = array.map{"Element \($0)"} // "["Element 2", "Element 3", "Element 1", "Element 4",
"Element 5"]\n"
클로저 정의하기
클로저를 사용하는 함수 작성
func add(i: Int, j: Int) -> Int {
let sum = i + j
return sum
}
let ret = add(1,j: 2)
print("1 + 2 = \(ret)")
// 위 함수에 클로저 파라미터로 추가
func add(i: Int, j: Int, handler: (Int) -> Void) {
let sum = i + j
handler(sum)
}
// 클로저 코드를 정의하면서 함수 호출
add(3, j: 4, handler: { (result: Int) -> Void in
print("3 + 4 = \(result)") // "3 + 4 = 7\n"
print("")
})
// 파라미터 타입 생략, Trailing closure 적용
add(5, j: 6) { result -> Void in print("5 + 6 = \(result)")}
옵셔널 타입
파라미터 형태의 클로저가 옵셔널일 수도 있다. 클로저 자체가 옵셔널이므로 클로저 타입 정의를 괄호로 감싸고 ?나 !를 붙인다.
func sub(i: Int, j: Int, handler: ((Int) -> Void)?) {
let sum = i - j
handler?(sum)
}
클로저 반환
클로저를 반환하는 함수
func makePrintRandomNumber(max: Int) -> () -> () {
return { () -> () in
let result = Int(arc4random()) % max
print("\(result)")
}
}
let randomClosure = makePrintRandomNumber(10)
randomClosure()
randomClosure()
// 함수 내부에 함수를 반환하도록 작성한 함수
func makePrintNumber(max: Int) -> () {
func printRandom() {
let result = Int(arc4random()) % max
print(result)
}
return printRandom()
}
댓글