오늘은 Swift에서 클로저에 대해 이야기해보려고 합니다.
클로저는 간단히 말해서 코드 덩어리라고 할 수 있어요. 이 코드 덩어리는 변수나 상수에 저장되거나, 함수에 전달되거나, 함수의 반환값이 될 수도 있죠. 다른 언어에서의 익명 함수나 람다 표현식과 비슷한 개념이라고 생각하면 됩니다.
클로저에는 크게 세 가지 형태가 있어요:
1. 전역 함수: 이름이 붙어있고, 어떤 값도 캡처하지 않는 클로저입니다.
2. 중첩 함수: 이름이 있고, 둘러싼 함수의 값을 캡처할 수 있는 클로저입니다.
3. 클로저 표현식: 주변의 값을 캡처할 수 있는, 이름 없는 클로저입니다.
이 중 '캡처'라는 단어가 나오는데, 이 부분에 대해서는 나중에 더 자세히 설명할게요. 지금은 클로저를 어떻게 사용하는지부터 살펴보죠.
클로저 표현식은 이렇게 작성됩니다
{ (매개변수) -> 반환 타입 in
실행할 코드
}
이 클로저는 파라미터로 inout
과 가변 파라미터를 사용할 수 있어요. 그리고 파라미터나 반환 타입으로 튜플도 사용할 수 있죠. 하지만 기본값을 가질 수는 없어요.
아래는 sorted
메서드에서 클로저를 사용한 예제입니다
let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
func backward(_ s1: String, _ s2: String) -> Bool {
return s1 > s2
}
var reversedNames = names.sorted(by: backward)
위 코드는 이름 배열을 정렬하는 예제인데, 클로저를 사용하면 더 간단하게 할 수 있습니다
reversedNames = names.sorted(by: { (s1: String, s2: String) -> Bool in
return s1 > s2
})
정렬 클로저의 타입은 (String, String) -> Bool
로 추론될 수 있어요. 그래서 반환 타입을 생략하고 이렇게 간단하게 작성할 수 있습니다
reversedNames = names.sorted(by: { s1, s2 in return s1 > s2 })
더 나아가서, return
키워드도 생략할 수 있어요
reversedNames = names.sorted(by: { s1, s2 in s1 > s2 })
Swift는 인라인 클로저에서 $0
, $1
같은 짧은 인수 이름을 제공합니다. 이렇게 사용하면 코드가 더 깔끔해지죠
reversedNames = names.sorted(by: { $0 > $1 })
후행 클로저는 함수의 마지막 매개변수로 클로저를 전달할 때 사용하는 방법인데, 이렇게 하면 코드의 가독성이 좋아집니다.
someFunctionThatTakesAClosure() {
// 클로저의 본문
}
sorted
함수에서도 후행 클로저를 사용할 수 있습니다
reversedNames = names.sorted { $0 > $1 }
캡처란, 클로저 내부에서 사용되는 외부 변수나 상수를 클로저가 정의된 컨텍스트로부터 참조하는 것을 말해요. 이게 무슨 뜻이냐면, 클로저가 만들어질 때 그 주변에 있는 변수나 상수를 기억해 둔다는 거죠.
아래 예제를 보면 이해가 쉬울 거예요
func makeIncrementer(forIncrement amount: Int) -> () -> Int {
var runningTotal = 0
func incrementer() -> Int {
runningTotal += amount
return runningTotal
}
return incrementer
}
이 함수에서 runningTotal
과 amount
는 클로저에 의해 캡처되기 때문에, 함수가 끝나더라도 값이 유지됩니다.
let incrementByTen = makeIncrementer(forIncrement: 10)
incrementByTen() // 10을 반환
incrementByTen() // 20을 반환
{ (매개변수) -> 반환 타입 in 실행 코드 }
>
와 파라미터의 소괄호 생략 가능.$0
, $1
등 짧은 인수 이름 제공, in
키워드 생략 가능.클로저는 코드 덩어리로 변수나 상수에 할당될 수 있고, 함수로 전달되거나 반환될 수 있습니다. Swift의 클로저는 익명 함수나 람다와 유사하지만, 다양한 형태와 강력한 기능을 제공하죠. 특히 타입 추론, 짧은 인수 이름, 후행 클로저 등의 기능을 통해 클로저를 훨씬 간편하게 사용할 수 있습니다.
다음 시간에는 탈출 클로저에 대해 알아보겠습니다.
출처
https://bbiguduk.gitbook.io/swift/language-guide-1/closures#trailing-closures