지난번 포스팅에서는 클로저에 대한 개념과 클로저 사용 방법에 대해서 자세히 살펴보았습니다. 이번 포스팅에서는 후행 클로저에 대해서 살펴보고 후행 클로저는 어떻게 쓰이는지 소스 코드와 함께 살펴보도록 하겠습니다.
후행 클로저(trailing closure)
우선 후행 클로저란 무엇이고 왜 사용하는 것일까요?
Swift에서 후행 클로저(trailing closure)는 함수의 마지막 인자로 전달되는 클로저입니다. 일반적으로 함수 호출 시에 클로저를 사용할 때, 매개변수 목록 안에 인라인으로 작성하는 것이 일반적입니다. 하지만 후행 클로저를 사용하면 함수 호출 구문을 더 간결하고 가독성 있게 만들 수 있기 때문에 후행 클로저를 사용합니다.
일반적인 클로저와 후행 클로저의 차이점
Swift에서 클로저는 일급 객체로서 함수와 유사한 기능을 수행합니다. 클로저는 코드 블록으로, 독립적으로 사용하거나 함수의 인자로 전달할 수 있습니다.
후행 클로저(Trailing Closure)는 클로저를 함수 호출 구문의 마지막 인자로 전달하는 특별한 문법적인 기능입니다. 이것은 가독성을 높이고 코드를 간결하게 작성하는 데 도움을 줍니다.
클로저와 후행 클로저의 주요 차이점은 다음과 같습니다.
- 문법적인 차이: 일반적인 클로저는 함수 호출 구문 내부에 인라인으로 작성됩니다. 반면, 후행 클로저는 함수 호출 구문 외부에 위치하여 가독성을 향상시킵니다.
- 매개변수 목록: 일반적인 클로저는 매개변수 목록과 반환 타입을 명시해야 합니다. 하지만 후행 클로저에서는 매개변수 목록과 반환 타입을 생략할 수 있으며, 컴파일러가 타입 추론을 통해 자동으로 추론합니다.
- 중괄호 사용: 일반적인 클로저에서 여러 줄의 코드를 작성하기 위해서는 중괄호 {}를 사용하여 코드 블록을 정의해야 합니다. 하지만 후행 클로저에서 여러 줄의 코드를 작성할 때에도 중괄호 {}를 사용할 수 있지만, 생략하고 한 줄짜리 표현식 형태도 가능합니다.
후행 클로저 사용법
후행 클로저를 사용하는 방법을 소스 코드로 한 번 살펴보겠습니다.
func someFunctionWithClosure(closure: () -> Void) {
// 함수 내부에서 클로저 실행
closure()
}
// 후행 클로저 사용 예시
someFunctionWithClosure() {
// 클로저의 내용을 여기에 작성
}
위의 예제에서 someFunctionWithClosure는 closure라는 이름의 매개변수를 받고, 이 매개변수는 () -> Void 타입의 클로저입니다. 이 함수를 호출할 때, 후행 클로저 문법을 사용하여 마지막 인자인 closure를 전달할 수 있습니다.
클로저가 길거나 복잡한 경우에 후행 클로저를 사용하면 코드의 가독성이 향상됩니다. 또한 여러 줄에 걸쳐 작성된 경우, 중괄호 {} 안에서 자유롭게 들여쓰기하여 코드 구조를 명확하게 표현할 수도 있습니다.
물론, 매개변수가 없거나 다른 매개변수와 함께 사용되더라도 후행 클로저 문법을 적용할 수 있습니다. 단 마지막 위치에 위치해야 한다는 점을 유의해야 합니다.
클로저 축약 표현
클로저 축약 표현에 대해서도 소스 코드와 함께 보겠습니다.
1. 매개변수 및 반환 타입의 생략
// 축약 전
let closure1: (Int, Int) -> Int = { (a: Int, b: Int) -> Int in
return a + b
}
// 축약 후
let closure1: (Int, Int) -> Int = { a, b in
return a + b
}
2. 단일 표현식 클로저의 반환 생략
// 축약 전
let closure2: (Int) -> Bool = { (number: Int) -> Bool in
return number % 2 == 0
}
// 축약 후
let closure2: (Int) -> Bool = { number in
number % 2 == 0
}
3. 암시적 매개변수 이름 사용 ($)
// 축약 전
let numbers = [1, 2, 3]
let mappedNumbers = numbers.map({ (number: Int) -> String in
return "\(number)"
})
// 축약 후 ($0은 첫 번째 매개변수를 의미)
let numbers = [1, 2, 3]
let mappedNumbers = numbers.map({ "\($0)" })
4. 메소드를 클로저로 사용할 때 self 생략하기 (@escaping과 함께)
class SomeClass {
var value: String
init(value: String) {
self.value = value
// escapeClosure는 @escaping 속성이 필요합니다.
someMethodWithClosure(closure: escapeClosure)
// noEscapeClosure는 @escaping 속성이 필요하지 않습니다.
someMethodWithClosure(closure: noEscapeClosure)
}
func someMethodWithClosure(closure: () -> Void) {
// ...
}
func escapeClosure() {
print(self.value)
}
func noEscapeClosure() {
print(value)
}
}
클로저를 축약하는 방법
- 리턴형을 생략한다.
- 매개변수를 생략하고 단축인자(shorthand argument name)를 사용한다.
- in도 생략 가능하다.
- return문 자체를 생략할 수 있다.
감사합니다.
틀린 부분이 있거나 더 좋은 내용 훈수 환영합니다!
공감과 댓글 부탁드립니다.
'Apple > Swift' 카테고리의 다른 글
[Swift] 객체 인스턴스(object instance) (0) | 2023.10.20 |
---|---|
[Swift] 저장 프로퍼티와 지연 저장 프로퍼티(Stored Properties, Lazy Stored Properties) (2) | 2023.10.19 |
[Swift] 클로저 개념 완벽 이해하기 (0) | 2023.10.17 |
[Swift] 클로저(Closure) (0) | 2023.10.16 |
[Swift] 1급 객체 (first class object), 1급 시민 (first class citizen) (0) | 2023.10.13 |