'클로저의 경량화'란 클로저 문법 사용 방식을 최적화하여 단순하게 코드를 작성하는 방식을 말한다.
클로저를 정식으로 쓰면 아래와 같다.
{ (파라미터 이름 : 파라미터 타입) -> 리턴 타입 in 실행 구문 }
하지만 swift 코드를 보면 대부분 경량화(간략화된) 방법으로 많이 사용하는 것을 알 수 있다. 따라서 위의 클로저를 어떻게 경량화하는지 꼭 알고 넘어가야할 필요가 있다.
2.1~2.4 목차에서 클로저를 최적화, 단순화, 경량화해갈 것인데, 이 때 사용할 생략되지 않은 기본 클로저를 아래에 적어보겠다.
alphabet이라는 배열을 선언하였다.
그리고 sorted 정렬해주는 펑션에 by라는 파라미터 네임에 문자열을 오름차순으로 정렬하여 리턴하는 클로저를 전달해주었다. (물론 sorted 펑션은 기본적으로 오름차순 정렬이긴 하다.)
Swift에는 타입 유추 기능이 있기 때문에 클로저(익명함수)의 파라미터 타입을 생략해도 된다.
예시를 살펴보자.
s1과 s2 파라미터의 Type인 String이 생략되었다.
2.1.1. 코드에서 -> Bool 이 사라졌다.
return 이라는 키워드 자체를 생략할 수 있다.
2.1. 코드에서 s1 < s2 앞에 return 키워드가 사라졌다.
파라미터도 생략이 가능하다. 아니 return 키워드도 생략이 가능하지 않았던가?
어떻게 가능할까?
바로 '인자 이름 축약 (Shortand Argument Names)'을 통해 파라미터 생략이 가능하다.
(참고로 'argument = 인자 = 인수' 모두 다 같은 말이다. )
2.2. 코드가 아래와 같이 생략되었다.
"$와 숫자의 조합"을 통해 파라미터를 가리켜 수행하고자 하는 바를 실현할 수 있다.
이 예시 코드에서는 &0은 s1: String을, &1은 s2: String을 의미한다.
파라미터가 생략이 되면서 in도 자연스럽게 생략이 된다.
2.3. 코드를 더 단순화할 수가 있을까?
그렇다. 여기서 어떻게 더 단순화 할 수 있지..?!
바로 "후행클로저(Trailing Closure)"를 이용하면 가능하다.
후행클로저(Trailing Closure)란 펑션의 마지막 인자(argument)에 클로저가 온다면 펑션 소괄호( )의 후행으로 즉, 뒤로 빼서 경량화 하는 기법을 말한다.
펑션의 후행으로 뺀다는게 무슨 말일까?
펑션의 소괄호( ) 밖으로 클로저 { ... }를 뺀다는 의미이다.
아래 예시를 봐보자.
2.3. 코드에서 소괄호( ) 안에 있던 { } 클로저 블럭이 소괄호( )의 후행으로 { } 빠져 나왔다.
여기서 좀 더 간략화할 수 있다. 정말 그렇다고??
네.
위의 코드에서 소괄호( )가 생략되었다.
소괄호를 생략할 수 있었던 이유는 파라미터가 클로저 한 개였기 떄문이다.
🚨 만약 파라미터가 여러개라면 소괄호( )는 생략될 수 없다!
callClosure 라는 펑션을 정의하였다.
callClosure는 testClosure라는 이름으로 클로저를 파라미터로 받은 후, 펑션 안에서 클로저를 수행한다.
testClosure()
callClosure를 호출하는 부분에서 달라지는 점들이 있다.
후행 클로저 사용 전과 달라진 점은 아래와 같다.
파라미터와 리턴이 생략되었고, 타입도 생략되었다. ('2.1. 타입 생략', '2.2. 리턴 생략', '2.3. 파라미터 생략' 참고)
그에 따라 in도 생략되었다.
인자가 하나밖에 없는데 그것이 클로저이므로 후행 클로저로 작성하였다. (' 2.4.1. 클로저를 소괄호( ) 뒤로 이동시키기' 참고)
클로저 하나밖에 없으므로 ( )도 생략되었다. ('2.4.2. 소괄호( ) 생략' 참고)
결국에는 호출하려고 하는 callClosure 펑션 바로 뒤에 클로저{ }를 여고 수행하고자 하는 기능을 작성하기만 하면 된다.
매우 편리하지 않은가?
참고로 애초에 callClosure를 호출할때부터 아래와 같이 2가지 선택지가 뜬다.
🙋 클로저를 경량화하는 방법을 정리하면서 느낀 점은.. "웬만한거는 다 생략하는구나."이다...ㅋㅋ 그 다음편 [iOS / Swift] 클로저의 캡쳐리스트 - 클로저 3편에서는 클로저의 캡쳐리스트라는 개념을 다뤄보겠다.
어렵다 어려워,,,후...