[swift] 클로저의 활용 방법

클로저는 Swift에서 매우 강력하고 유용한 기능입니다. 클로저는 일급 시민으로서 변수에 할당하거나 인자로 전달할 수 있습니다. 이번 글에서는 클로저의 다양한 활용 방법에 대해 알아보겠습니다.

1. 매개변수와 반환 값으로 사용하기

클로저는 함수와 마찬가지로 매개변수를 받고 값을 반환할 수 있습니다. 예를 들어, 두 개의 Int 값을 더하는 클로저를 정의해보겠습니다.

let addClosure: (Int, Int) -> Int = { (a, b) in
    return a + b
}

let result = addClosure(3, 5)
print(result) // 8

위의 예제에서 addClosure는 두 개의 Int 값을 받아 더한 후 결과를 반환하는 클로저입니다. 클로저를 사용하여 간단한 수식을 실행할 수 있습니다.

2. 타입 유추를 통한 간결한 구현

Swift는 타입 유추 기능을 제공하여 클로저 구현을 더욱 간결하게 할 수 있습니다. 타입을 명시적으로 선언하지 않아도 Swift 컴파일러가 자동으로 타입을 추론합니다.

예를 들어, 배열에 저장된 문자열을 길이 순으로 정렬하는 클로저를 작성할 때 타입을 명시적으로 선언할 필요가 없습니다.

let strings = ["apple", "banana", "cherry", "date"]
let sortedStrings = strings.sorted { $0.count < $1.count }

print(sortedStrings) // ["date", "apple", "cherry", "banana"]

위의 예제에서 sorted 메서드는 클로저를 인자로 받으며, sorted 메서드는 자동으로 해당 클로저의 타입을 추론합니다.

3. 탈출 클로저

클로저는 기본적으로 비동기 작업에서 주로 사용되는 탈출 클로저입니다. 탈출 클로저는 해당 범위를 벗어난 후에도 호출될 수 있습니다.

예를 들어, 비동기적으로 데이터를 가져오는 함수에서 클로저를 사용하면 작업이 완료된 후에 클로저가 호출됩니다.

func fetchData(completion: @escaping (String) -> Void) {
    DispatchQueue.global().async {
        // 데이터 가져오는 작업
        let data = "Fetched Data"
        
        DispatchQueue.main.async {
            completion(data)
        }
    }
}

fetchData { result in
    print(result)
}

위의 예제에서 fetchData 함수는 비동기적으로 데이터를 가져와서 completion 클로저를 호출합니다. fetchData 함수를 호출하는 부분에서 클로저를 작성하여 데이터를 받아온 후에 원하는 동작을 수행할 수 있습니다.

4. 클로저의 간소화

Swift는 많은 편의 기능을 제공하여 클로저를 더욱 간단히 작성할 수 있도록 도와줍니다. 예를 들어, 클로저에서 단 한 줄의 표현식만 사용한다면 return 키워드를 생략할 수 있습니다.

let numbers = [1, 2, 3, 4, 5]
let squaredNumbers = numbers.map { $0 * $0 }

print(squaredNumbers) // [1, 4, 9, 16, 25]

위의 예제에서 map 메서드는 클로저를 인자로 받으며, 각 원소에 대해 제곱값을 계산하여 새로운 배열을 반환합니다. 클로저는 단 한 줄로 표현되므로 return 키워드를 생략할 수 있습니다.

결론

클로저는 Swift에서 매우 강력하고 유용한 기능입니다. 이 글에서는 클로저의 다양한 활용 방법에 대해 알아보았습니다. 매개변수와 반환 값으로 사용하거나 타입 유추를 통해 간결하게 구현할 수 있으며, 탈출 클로저와 간소화된 문법을 사용하여 더 효율적으로 코드를 작성할 수 있습니다. 클로저의 활용을 통해 Swift 개발을 더욱 편리하고 효율적으로 진행할 수 있습니다.

참고 자료