사실 저번 시간에 작성했던 글에서 클로저가 헷갈리는 이유 중 하나를 빼먹었습니다.
그것은 바로,
후행 클로저(Trailing Closure)라는 친구입니다.
아니 이거는 왜 저번 포스팅에 같이 안 썼냐고요?
까먹었습니다.
ㅎㅎ;
그리고 한 글에 너무 많은 것이 들어가면 읽기 힘들잖습니까?
배려해드렸습니다. 감사하십시오 휴먼.
그럼,
후행 클로저는, 뒤에 있는 클로저입니다.
아니 진짜 그게 다입니다...
다른 말로는 뒤따라오는 클로저라고 해도 되겠네요.
트레일러를 생각하시면 됩니다.
요렇게 앞에 가는 차에 딸려 가는 캠핑 트레일러처럼요.
그래서 본론으로 돌아와서, 후행 클로저를 이해하려면,
는 것을 알아야 합니다.
모르셨다고요?
이제 아시게 되셨으니 감사하십시오 휴먼.
...여튼...
사실 클로저에 대한 고민을 하게되는 시점이,
고차함수 map, filter, reduce 삼형제를 접하는 시점이기에
(대충 개노답삼형제 짤 상상해주세요 만들어오기 상당히 귀찮네요)
함수에서 다른 함수를 인수로 받는다는 사실을 인지하지 못 하더라도,
나도 모르게 써 보았거나, 어렴풋이 알고는 있을 확률이 높습니다.
그럼 filter를 예로 들어서 한번 볼까요?
클로저 이해에는 생략된 것을 모두 풀어서 쓰는 것 만큼 효과적인 방법이 없죠.
저번 글을 읽으셨다면 위 스크린샷의 코드가 무리 없이 해석이 가능할 것입니다.
안 읽으셨다고요?
빨리 가서 읽고 오십셔. 위에 시리즈에 링크까지 친절히 걸려있습니다.
기다리고 있겠습니다.
하나하나 찬찬히 뜯어봅시다.
"스트링치즈먹고싶다".filter({ (char: Character) -> Bool in return char != "스" })
// 위를 실행하면 "트링치즈먹고싶다"를 반환합니다.
저번 글에서 설명했던 생략되는 과정을 속성으로 다시 봅시다.
// 풀버전
"스트링치즈먹고싶다".filter({ (char: Character) -> Bool in return char != "스" })
// 클로저의 타입 선언 생략하기 (입력, 반환되는 값에서 추론)
"스트링치즈먹고싶다".filter({ char in return char != "스" })
// return문 생략
"스트링치즈먹고싶다".filter({ char in char != "스" })
// Shorthand Argument를 사용하여 in 구문 생략하기
"스트링치즈먹고싶다".filter({ $0 != "스" })
참 쉽죠?
근데 여기서 이 클로저가, 전달하려고 하는 함수 또는 메서드의 마지막 or 유일한 클로저 전달인자라면?
후행 클로저가 사용이 가능해지는 것입니다.
filter 함수의 경우, 유일한 클로저 전달인자이기에, 후행 클로저를 사용할 수 있습니다.
// 후행 클로저 사용
"스트링치즈먹고싶다".filter() { $0 != "스" }
심지어 함수의(안에) 또 다른 전달인자가 없다면?
괄호마저도 날려버릴 수 있습니다.
// 후행 클로저 사용, 괄호 생략
"스트링치즈먹고싶다".filter { $0 != "스" }
참 깔끔하다 그죠?
물론 이런 경우에도 깔끔해 보이긴 하지만,
후행 클로저의 진가는 괄호 안에 다른 전달인자가 있을 때 발휘됩니다.
스샷 한 장으로 갈음하죠.
설명이... 필요한지?
아, 다만 위 스샷의 경우, 클로저 제외 전달인자가 존재하기에, 괄호를 날려버릴 수는 없습니다.
그래도 굉장히 깔끔해지니 기분이 좋지 않으신가요?
아니라고요...?
일단 제 기분은 좋으니 저만 행복하다면 OK입니다.
후행 클로저는 Swift 전반에 널리 사용되기 때문에 필히 익숙해지는 것이 좋습니다.
그럼 다음 시간에 또 뵙죠.
이 포스트는 아래 자료에 기반하여 작성되었습니다:
Swift 한국어 - 클로저 (Closures) [링크]
스위프트 프로그래밍 3판 - 야곰
후행이라길래 애교인 줄 알았어요 후행 ㅜ ㅋㅋㅋㅋㅋ 트렐링 클로저 안그래도 공부하려고 했는데 잘 보고 갑니둥