2019. 5. 7. 11:30ㆍSwift + iOS
정의
클로저는 일정 기능을 하는 코드를 하나의 블록으로 모아놓은 것이다.
- 클로저는 상수 안에 들어 있지 않아도 블럭 그대로 존재할 수 있는 코드의 블럭이다.
- 클로저는 변수나 상수가 선언된 위치에서 참조(reference)를 capture하고 저장이 가능한데, 이를 변수나 상수의 클로징(잠금)이라고 부른다. 이 클로징 때문에 클로저가 클로저로 불리게 된다.
- Cf. 함수는 이름이 있는 클로저이다. 함수는 클로저에 포함된 개념이므로 모든 함수는 클로저이다.
함수는 일급시민인데, 그렇기 때문에 함수를 타입으로 지정하거나, 인자값으로 넘기거나, 리턴값으로 받을 수 있는 등 함수 자체를 값으로 취급할 수 있다.
클로저도 일급시민*이기 때문에 파라미터, 변수, 상수 등으로 저장과 전달을 할 수 있다.
문법
클로저의 형태
- 이름이 있으면서 어떤 값도 획득(캡쳐)하지 않는 전역함수의 형태
- 이름이 있으면서 다른 함수 내부의 값을 획득할 수 있는 중첩된 함수의 형태
- 이름이 없고 주변 문맥에 따라 값을 획득할 수 있는 축약 문법으로 작성한 형태
클로저 간결화
- 컨텍스트에서 파라미터와 리턴값의 타입을 추론할 수 있기 때문에 파라미터와 리턴값의 타입을 생략할 수 있다.
- 클로저에 단 한 줄의 표현만 들어있다면 암시적으로 이를 반환 값으로 취급한다.
- 축약된 전달인자 이름을 사용할 수 있다.
- 후행 클로저 문법을 사용할 수 있다.
클로저를 이용하면 동일한 기능을 하는 코드를 간결하게 표현할 수 있다.
sort(by:) 메서드는 클로저를 통해 어떻게 정렬할 것인지에 대한 정보를 받아 처리하고 결괏값을 배열로 돌려준다.
(Element, Element) -> Bool 부분이 클로저이다.
let value = [15, 5, 2, 3, 11, 7]
value.sorted(by: {
(left: Int, right: Int) -> Bool in
if left > right {
return true
} else {
return false
}
})
// [15, 11, 7, 5, 3, 2]
이 클로저 표현식은 여러가지 형태로 간결화 할 수 있다.
일단 여러줄로 표현해 놓은 클로저 표현식을 한 줄로 줄여서 표현해보자.
value.sorted(by: {(left: Int, right: Int) -> Bool in return left > right })
1. 파라미터와 리턴값 생략
value.sorted(by: {(left, right) in return left > right })
Int와 Bool이 생략된 것을 볼 수 있다.
sorted()가 받아야되는 클로저의 타입이 정해져 있기 때문에 스위프트는 이를 기반으로 파라미터와 리턴의 타입을 추론할 수 있다. 그렇기 때문에 생략을 하더라도 스위프트가 찰떡같이 알아서 처리해준다.
2. 후행 클로저 사용
value.sorted() {(left, right) in return left > right }
value.sorted {(left, right) in return left > right }
클로저가 함수의 마지막 파라미터에 들어갈 경우 사용할 수 있다.
sorted() 로 사용가능하고, sorted(by: )의 소괄호까지도 생략해서 사용할 수 있다.
3. 단축 인자 사용
value.sorted {
return $0 > $1
}
$0, $1이 갑자기 나와서 엥? 할 수도 있겠지만 여태까지의 코드와 같은 내용이라고 보면 된다.
$0은 클로저에 전달된 첫번째 파라미터, $1은 클로저에 전달된 두번째 파라미터를 뜻한다.
4. 암시적 반환 표현 사용
value.sorted { $0 > $1 }
이렇게 클로저 안에 한 줄의 표현만 있다면 스위프트는 '당연히 이게 return 이겠지~' 라고 생각해서 이 코드를 return 문으로 처리한다. 똑똑한 스위프트...
참고
스위프트 프로그래밍 2판, 야곰, 한빛미디어
https://ko.wikipedia.org/wiki/일급_객체
https://docs.swift.org/swift-book/LanguageGuide/Closures.html#
'Swift + iOS' 카테고리의 다른 글
iOS. 네비게이션 컨트롤러 (0) | 2019.07.30 |
---|---|
Swift. Extension (0) | 2019.04.25 |
Xcode. Xcode 디버깅 팁 (7) | 2019.04.22 |
Swift. 옵셔널 (0) | 2019.04.18 |