- 클로저란? 함수를 객체처럼 사용하며, 함수처럼 정의한 후에 사용 시에 부가 기능을 더 추가할 수 있도록 한 API를 의미하며 형태는 함수나 코드 블록으로 구성된다.
- 클로저 사용 API
- 클로저의 함수 타입을 결정한다.
- 함수 타입 : 함수 객체를 참조 변수로 사용할 때의 타입을 의미한다.
- 사용방법
- 파라미터가 없고, 반환값이 없는 함수 타입 : () -> (), () -> Void
- 파라미터가 있고, 반환값이 있는 함수 타입 : (Int) -> Int
- 클로저 표현식
- 별도의 함수 정의 없이 Inline 방식으로 작성한다.클로저 표현식// 방식 
 { (파라미터, ...) -> Return Type in
 // 코드
 }
 
 // 예시
 array.sorted(by : {(a : Int, b : Int) -> Bool in
 return a < b
 })
- 클로저 표현식 단축
- 파라미터 타입 선언 생략
 array.sorted(by : {a, b -> Bool in return a < b})
- 1줄 return인 경우 return 생략
 array.sorted(by:{a, b -> Bool in a<b})
- 반환 타입 선언 생략
 array.sorted(by:{a, b in a<b})
- 파라미터 선언 생략
 array.sorted(by : {$0 < $1})
- 반환 값으로 사용한다.반환 값으로 사용// 반환 값의 함수 타입 : () -> Void 
 func greeting() -> (() -> Void) {
 // 함수 타입이 () -> Void 로 함수로 구성
 func sayGoodmorning() {
 print("Good Morning Everyone")
 }
 return sayGoodmorning
 }
 
 // 사용하기
 let ret = greeting()
 ret() // Good Morning Everyone 출력
 
 // 클로저 표현식으로 작성(Inline으로 작성)
 // 코드 블록으로 구성
 func greeting() -> (() -> Void) {
 return { () -> Void in
 print("How are you")
 }
 }
- 파라미터로 사용한다.파라미터 사용하기// 원래 함수 
 func add(_ i : Int, _ j : Int) -> Int {
 let sum = i + j
 return sum
 }
 // 함수 타입 : (Int) -> Void
 func add(_ i : Int, _ j : Int, _ handle : ((Int) -> Void)) {
 let sum = i + j
 handle(sum)
 }
 
 
 // 사용하기
 add(3, 4, {(result : Int) -> Void in
 print("3 + 4 = \(result)")
 })
- 프로퍼티에 사용한다.프로퍼티에 사용// 클래스 정의 
 // 함수 타입 : () -> Int
 class MyClass {
 var property : (() -> Int)!
 }
 
 // 사용하기
 var obj = MyClass()
 obj.propery = {
 return 0
 }
- 클로저에서 프로퍼티 접근 : self를 사용하여 접근프로퍼티 접근// 클래스 정의 
 // 함수 타입 : () -> Void
 class MyClass {
 var value = 0
 
 func showAndPrint() -> (() -> Void) {
 return {
 print(self.value)
 }
 }
 }
- 클로저와 타입 알리아스
- 타입 알리아스는 타입에 이름을 주어 해당 타입 대신에 타입 알리아스로 정한 이름으로 대체가 가능하게 한 방법이다.타입 알리아스// 타입 알리아스 정의 
 typealias Century = Int
 // 타입 알리아스 사용
 var thisEra : Century = 12 // Int 대신 사용 가능
 
 // 클로저에서 타입 알리아스 활용
 // 원래 함수
 func add(_ i : Int, _ j : Int) -> Int {
 let sum = i + j
 return sum
 }
 // 함수 타입 : (Int) -> Void
 func add(_ i : Int, _ j : Int, _ handle : ((Int) -> Void)) {
 let sum = i + j
 handle(sum)
 }
 // 타입 알리아스 정의
 typealias ResultHandler = (Int) -> Void
 // 함수 타입 : (Int) -> Void
 func add(_ i : Int, _ j : Int, _ handle : ResultHandler) {
 let sum = i + j
 handle(sum)
 }
 // 타입 알리아스에 정의된 이름으로 대체 가능