전역 함수와 중첩 함수는 클로저의 특별한 경우로 클로저는 다음 세 가지 형태 중 하나를 갖는다.
- 전역 함수 : 이름이 있고 값을 캡쳐하지 않는 클로저
- 중첩 함수 : 이름이 있고 둘러싼 함수에서 값을 캡쳐할 수 있는 클로저
- 클로저 표현 : 관련 문맥(context)에서 값을 캡쳐할 수 있고 이름이 없는 클로저
클로저 표현은 최적화되어 간결하고 명확하다.
[최적화 표현]
{ (parameters) -> return type in
statements
}
괄호 안에 파라미터를 쓰고 -> 반환 타입을 결정하고 'in' 키워드로 본문을 시작한다.
func name(parameters) -> return type {
statements
}
함수와 다르게 클로저는 이름이 없고 파라미터와 반환 형식 모두 중괄호 안에 쓴다.
정렬 메서드 (The Sorted Method) : sorted(by:)
Swift 표준 라이브러리에서 제공하는 배열을 정리하는 메서드
by 이후에는 어떤 방법으로 정렬을 수행할건지에 대한 클로저를 넣는다.
(sorted(by:)메소드는 원본 배열은 변경하지 않는다.)
String으로 구성된 names 배열을 함수를 이용해 sorted(by:)메서드로 정렬하는 방법
func backward(_ s1: String, _ s2: String) -> Bool {
return s1 > s2
}
var reversedNames = names.sorted(by: backward)
함수는 비교적 길기 때문에 다양한 문번을 이용한 클로저를 통해 정렬할 수 있다.
reversedNames = names.sorted(by: { (s1: String, s2: String) -> Bool in
return s1 > s2
})
위와 같이 함수로 정의된 형태가 아닌 인자로 들어간 형태인 클로저를 '인라인 클로저'라고 한다.
클로저의 길이가 짧을 때는 한 줄로 쓸 수 있다.
클로저가 메서드의 인자로 전달된 경우와 같이 파라미터와 반환 타입을 유추할 수 있을 경우 생략 가능하다.
String 배열에서 sorted(by)의 인자로 사용되는 클로저는 이미 (String, String) -> Bool 타입의 인자를 받아야 할 것을 알기에 생략할 수 있다.
reversedNames = names.sorted(by: { s1, s2 in return s1 > s2 } )
단일 클로저에서는 'return' 키워드도 생략이 가능하다.
reversedNames = names.sorted(by: { s1, s2 in s1 > s2 } )
Swift는 인라인 클로저에 자동으로 약식 인수 이름을 제공하는데 순서대로 $0, $1, $2 등의 이름으로 클로저의 인수 값을 참조하는 데 사용할 수 있다.
축약 인자를 사용하면 인자 값과 처리하는 인자 값이 같음을 알기에 인자를 입력받는 부분과 'in' 키워드를 생략할 수 있다.
reversedNames = names.sorted(by: { $0 > $1 } )
Swift의 String 타입 연산자에는 String끼리 비교할 수 있는 비교 연산자(>)가 있기 때문에 연산자로만 표현할 수 있다.
reversedNames = names.sorted(by: >)
참조 : Swift:Closures