클로저의 3가지 형태
1. 이름이 있고 어떤 값도 획득하지 않는 전역함수의 형태
2. 이름이 있고 다른 함수 내부의 값을 획득할 수 있는 중첩된 함수의 형태
3. 이름이 없고 주변 문맥에 따라 값을 획득할 수 있는 축약 문법으로 작성된 형태
특징
1. 파라미터와 리턴타입을 생략할 수 있다(문백을 통해 타입을 유추할 수 있기 때문)
2. 클로저에 단 한줄의 표현만 들어있다면 암시적으로 이를 반환 값으로 취급한다
3. 축약된 argument label 이름을 사용할 수 있다
4. trailing closure 문법을 사용할 수 있다
{(매개변수들) -> 리턴타입 in
실행코드
}
in
키워드매개변수 & 반환타입과 실행코드를 구분하기 위해 사용하는 키워드
함수의 마지막 차라미터로 위치하는 클로저는 함수의 소괄호를 닫은 루 작성해도 된다
클로저가 조금 길어지거나 가독성이 조금 떨어진다 싶으면 트레일링 클로저로 작성하면 좋다
단, 후행클로저는 맨 마지막 파라미터로 전달되는 클로저에만 해당되므로 전달인자로 클로저를 여러개 전달할때는 -> 맨 마지막 클로저만 후행 클로저로 사용할 수 있다
단 하나의 클로저만 파라미터로 전달하는 경우 -> 소괄호를 생략해도 된다
before
reversed = names.sorted() { (first: String, second: String) -> Bool in
return first > second
}
after
reversed = names.sorted { (first: String, second: String) -> Bool in
return first > second
}
// sorted(by areIncreasingIrder: (Element, Element) -> Bool ) -> [Element]
let names: [String] = ["A", "B", "f", "w", "t", "y"]
func backwards(first: String, second: String) -> Bool {
return first > second
}
// 오리지널
var reversed = names.sorted(by: {(first: String, second: String) -> Bool in
return first > second
})
// 소괄호 생략
reversed = names.sorted { (first: String, second: String) -> Bool in
return first > second
}
// 파라미터 타입 생략 (타입추론을 사용 / 적합한 타입을 준수하고 있다고 유추할 수 있기 때문에)
reversed = names.sorted { (first, second) -> Bool in
return first > second
}
// 리턴타입 생략
reversed = names.sorted { (first, second) in
return first > second
}
// 단축인자 이름 사용 & in 생략 ( in = 파라미터, 리턴타입 | 싫행코드를 구분하기 위해 사용했던 키워드 )
reversed = names.sorted {
return $0 > $1
}
// 리턴 키워드 생략 (클로저가 반환값을 가지는 클로저 이고, 내부의 실행문이 단 한줄이라면 암시적으로 해당 실행문을 반환값으로 사용할 수 있다)
reversed = names.sorted { $0 > $1 }
파라미터이름을 간결에서 표현할 수 있도록
첫번째 전달인자부터 $0, $1, $2 순서도 표현한다.
단축인자 표현을 사용하게 되면 매개변수 및 반환타입과 실행코드를 구분하기 위해 썼던 in
키워드를 사용할 필요가 없다.
함수나 클로저를 변수에 할당한다는 것은 클로저의 내용물, 즉 값을 할당하는 것이 아니라 해당 클로저의 참조
를 할당하는 것이다. 결국 클로저의 참조를 다른 상수에 할당해준다면 이는 두 상수가 모두 같은 클로저를 가리킨다는 뜻이다.
클로저에 참조가 있다? 클로저가 주소를 가진다?