조금 더 이해하기 쉬운 방식으로 클로저를 접해보자!
함수의 마지막 파라미터가 클로저일 때, 이를 파라미터 값 형식이 아닌 함수 뒤에 붙여 작성하는 문법이다. 이때 Argument Label은 생략된다!
ii) inline Closure : 클로저가 파라미터의 값 형식으로 함수 호출 구문 () 안에 작성되어 있는 것!
// i) 클로저 하나만 파라미터로 받는 함수
func doSomething(closure: () -> ()) {
closure()
}
// ii) inline Closure
doSomething(closure: { () -> () in
print("Hello")
})
but 이것도 코드 해석이 힘들고 헷갈리기 쉬움 SO
함수의 가장 마지막에 클로저를 꼬리처럼 덧붙여서 씀 => 후행 클로저!!!!
- 파라미터가 클로저 하나일 경우, 이 클로저는 첫 파라미터이자 마지막 파라미터이므로 트레일링 클로저 가능!
- "closure"라는 ArgumentLabel은 트레일링 클로저에선 생략됨!
- 파라미터가 클로저 하나일 경우 호출구문인 ()도 생략가능
// iii) trailing closure
doSomething () { () -> () in
print("Hello")
}
// iv) 파라미터가 클로저 하나일때!
doSomething { () -> () in
print("Hello")
}
func fetchData(success: () -> (), fail: () -> (
//do something...
}
fetchData(success: { () -> () in
print("Success")
}, fail: { () -> () in
print("Fail")
})
fetchData(success: { () -> () in
print("Success")
}) { () -> () in
print("Fail")
}
// 파라미터가 여러개임으로 () 함부로 생략하면 안됨!
반환타입이 생략 가능하다
컴파일러 상에서 어떤 타입을 반환할 지 알고 있다면 클로저에서는 반환타입을 명시해 주지 않아도 해석 가능
이때 반환타입은 생략이 가능하지만 in 키워드는 생략하면 안된다!
doSomething(closure: { (a: Int, b: Int, c: Int)
return a + b + c
})
// 반환타입 생략
doSomething(closure: { (a, b, c) in
return a + b + c
})
Parmeter Name과 in 키워드를 생략할 수도 있습니다
인라인 클로저에 $0, $1, $2(Parameter의 갯수만큼) 등 클로저의 인자값으로 참조하는데 사용할 수 있는 자동적으로 짧은 인자 이름이다.
선언에 클로저의 인자 목록을 생략할 수 있고 짧은 인자 이름의 수와 타입은 함수 타입에서 유추됩니다.
클로저 표현식이 전체 바디로 구성되기 때문에, in 키워드를 생략할 수도 있습니다
doSomething(closure: { (a, b, c) in
return a + b + c
})
// Shortand Argument Names
doSomething(closure: {
return $0 + $1 + $2
})
return 키워드 생략할 수 있다.
단일 표현 리터럴: 클로저 내부에 코드가 return 구문 하나만 남은 경우
이때는 return 키워드를 생략 가능하다.(암시적 반환)
하지만 단일 리턴문이 아닐경우 error 발생
doSomething(closure: {
$0 + $1 + $2
})
doSomething(closure: {
print("hello")
$0 + $1 + $2 // error : Missing return in a closure expected to return
})