[Swift iOS] 클로저(Closure)에 관하여

JB
6 min readOct 4, 2020

--

클로저란 코드뭉치로써 C나 Objective-C의 block, 자바의 람다식과 같은 역할을 합니다. 클로저의 특징은 전체적인 선언과 이름을 생략함으로써 간편하고 더 짧은 구문을 씀으로써 유용할 수 있습니다. 특히 하나 또는 여러개의 인자값을 사용하는 함수나 메소드를 사용할 때 더욱 유용합니다.

클로저는 정의된 그 문맥코드에서 변수나 상수를 캡쳐하고 저장하는 역할을 합니다. (Swift는 캡처된 모든 매모리 관리를 자동적으로 해주기때문에 캡처된 메모리 관리를 신경쓸 필요가 없습니다)

클로저와 함수(Function)의 관계적 특징

  • 모든 함수는 이름이 있고, 값에 대한 캡처를 하지않는 클로저
  • 중첩함수(Nested functions)들은 이름이 있고 함수의 정보를 가두어 값을 캡처할 수 있는 클로저
  • 클로저 표현은 이름없는 클로저 표현이며 값을 캡처할 수 있는 간단한 구문으로 쓰여짐

애플 공식문서에서 사용한 예제를 보도록 하겠습니다.

애플 공식문서에서는 sorted(by:) 라는 메소드를 제공하고있습니다. 이는 주어진 타입의 배열을 소팅(sorting)하여 값을 도출해 냅니다.

정석적인 메소드 사용 표현

reversedNames라는 변수안에 names안에 있는 배열들을 backward함수에 의하여 정렬해 주었습니다. (s1이 s2보다 더크면 리턴값이 true로 하게끔 정렬해주었습니다. = 알파벳이 더 높은순서대로)

여기서 backward함수를 클로저로 바꾼다면 코드를 조금 더 쉽게 알아볼 수 있을까요?

클로저의 문법 표현 (Closure Expression Syntax)

먼저 클로저 문법 표현을 알아보도록 하겠습니다.

클로저 문법 표현 format

이 표현을 응용하여 위의 reversedNames를 다시 정의해 본다면,

클로저를 이용한 reversedNames 구현

backward(_:_:) 함수와 같은 역할을 하는 (s1: String, s2: String) -> Bool으로 대체되었습니다.

다른 점은, 인자값과 리턴타입이 중괄호 안의 inline 클로저 표현에 있다는 것입니다.

즉, 위에서 언급했던

“전체적인 선언과 이름을 생략함으로써 간편하고 더 짧은 구문”

을 사용함으로써 간편하고 축약된 코드를 만들 수 있는 강력한 클로저 구문의 특징입니다.

위에서 보았던 클로저의 body는 “in” 키워드를 사용하여 선언이 됩니다.
이 “in” 키워드는 클로저의 인자값과 리턴타입이 끝났으니, 클로저의 body가 시작된다는 뜻 입니다.

문맥상의 추론 타입 (Inferring Type From Context)

Sorted(by:) 메소드는 string타입의 배열을 Bool값을 리턴하는 (String, String) -> Bool의 형태를 가지고 있습니다. 여기서의 (String, String)Bool의 타입들은 추론이 가능하기 때문에 생략이 가능하므로,

문맥상의 추론 타입

와 같이 타입을 생략 한 후 클로저를 구현해 주어도 됩니다.

단일 클로저 표현에서의 암시적 반환(Implicit Returns from Single-Expression Closures)

단일 클로저 표현에서는 암시적으로 “return”키워드를 생략하여

return 키워드 생략

와 같이 표현 해 줄 수 있습니다.

여기서 sorted(:by) 함수의 리턴 타입이 암시적으로 Bool 이라는 것을 알고 있습니다. 리턴 타입의 모호성이 없기 때문에 “return” 키워드는 생략될 수 있습니다.

인자값의 축약(Shorthand Argument Names)

스위프트에서는 inline 클로저에서 인자값의 축약형을 $0, $1, $2와 같이 제공해 주고 있습니다.

인자값의 축약형

예시에서의 $0 과 $1은 클로저의 첫번째, 두번째 String 인자값을 뜻합니다.

만약 축약형을 클로저에 사용한다면 클로저의 인자값을 생략 할 수 있고, 인자값의 타입도 추론(inferred) 됩니다. 또한, “in” 키워드도 생략 가능합니다.

연산자 메소드(Operator Methods)

스위프트에서 String타입인 2개의 인자값을 갖고 Bool 타입의 리턴 값을 가질 때 초과(greater-than operator)인 (>)을 사용 할 수 있습니다.

후행 클로저(Trailing Closures)

실무에서 정말 많이 쓰이는 클로저 중 하나이며, 정말 중요한 클로저 입니다!

함수에서의 클로저 표현식을 함수의 마지막 인자값으로 전달할 경우 후행 클로저는 유용하게 쓰일 수 있습니다. 긴 클로저 표현식에서의 후행 클로저를 사용한다면 함수의 괄호 밖에서 작성되어 사용되게 됩니다.

후행 클로저의 예시

지금까지 알아본 sorted(:by) 에적용시켜 본다면,

reversedName 변수값 도출에 후행 클로저 사용

만약, 클로저 표현식이 함수 또는 메소드의 유일한 인자값이고,
표현식을 후행 클로저로 사용 할시에는,
함수이름 뒤에 오는 소괄호 ( () ) 를 사용하지 않아도 됩니다.

후행 클로저사용시 소괄호 ( () ) 생략가능

--

--

JB
JB

Written by JB

iOS engineer @kakaobank

No responses yet