IMCAT.DEV
로그인 가입
Swift 입문 함수형

Swift 클로저(Closure) 기초

Swift 클로저(Closure) 기초 — 초급

클로저(Closure) 기초

1. 도입 (왜 배워야 하는가)

Swift에서 클로저는 매우 중요한 개념입니다. 클로저를 이해하면 코드의 재사용성과 가독성을 높일 수 있으며, 비동기 프로그래밍, 이벤트 처리, 데이터 조작 등 다양한 상황에서 유용하게 사용됩니다. 만약 클로저를 모른다면, 특히 비동기 작업이나 콜백 기능을 구현할 때 코드가 복잡해지고, 유지보수가 어려워질 수 있습니다. 예를 들어, API 호출 후 데이터를 처리하는 과정에서 클로저 없이 구현하면 코드가 비효율적으로 길어질 가능성이 큽니다.

2. 핵심 개념 설명

클로저는 일종의 "익명 함수"입니다. 함수와 비슷하게 재사용할 수 있으며, 변수를 캡처하고 상태를 유지할 수 있습니다. 실생활에서 클로저를 비유하자면, 요리사가 비법 소스를 미리 만들어 놓고 필요할 때마다 꺼내 쓰는 것과 같습니다. 요리사는 소스를 언제든지 사용할 수 있지만, 소스의 재료나 조리법은 외부와 분리되어 있습니다.

관련 용어 정리

용어설명
클로저함수처럼 동작하는 코드 블록
캡처클로저가 외부 변수에 접근하는 것
타입 추론Swift가 변수의 타입을 자동으로 추론

3. 기본 코드 예제

다음은 클로저의 기본적인 사용법을 보여주는 간단한 코드입니다.

// 클로저 선언
let greeting = {
    print("안녕하세요!")
}

// 클로저 호출
greeting()

실행 결과:

안녕하세요!

코드 한 줄씩 동작 설명:

  1. let greeting = { ... }: 클로저를 정의하고, greeting이라는 변수에 할당합니다. 이 클로저는 "안녕하세요!"라는 메시지를 출력합니다.
  2. greeting(): 정의한 클로저를 호출하여 실행합니다. 결과적으로 "안녕하세요!"가 출력됩니다.
  3. 4. 실전 활용 예제

    예제 1: 배열 정렬

    쇼핑몰에서 상품 목록을 가격에 따라 정렬할 때 클로저를 사용할 수 있습니다.

    let prices = [30000, 15000, 25000, 45000]
    let sortedPrices = prices.sorted(by: { $0 < $1 })
    
    print(sortedPrices) // [15000, 25000, 30000, 45000]

    상황 설명: 가격 배열을 오름차순으로 정렬하여 사용자에게 더 나은 쇼핑 경험을 제공합니다.

    예제 2: 비동기 처리

    API에서 데이터를 가져오는 경우 클로저를 사용하여 비동기적으로 데이터를 처리할 수 있습니다.

    func fetchData(completion: @escaping (String) -> Void) {
        DispatchQueue.global().async {
            // 데이터 가져오기 (모의)
            let data = "데이터 로드 완료"
            completion(data)
        }
    }
    
    fetchData { result in
        print(result) // 데이터 로드 완료
    }

    상황 설명: 네트워크에서 데이터를 가져온 후, 클로저를 통해 결과를 처리합니다.

    5. 흔한 실수와 주의사항

    실수 1: 클로저 내에서 캡처한 변수를 수정하기

    잘못된 코드:

    var count = 0
    let increment = {
        count += 1
    }
    increment()
    print(count) // 1

    올바른 코드:

    var count = 0
    let increment = { [count] in
        count += 1 // 컴파일 오류 발생, count는 수정할 수 없음
    }
    increment()
    print(count) // 0

    주의사항: 변수를 캡처할 때 값을 직접 수정하려면 inout을 사용하거나 다른 방법을 고려해야 함.

    실수 2: 클로저의 타입을 명시하지 않기

    잘못된 코드:

    let operation = {
        return 5 + 10
    } // 타입이 불명확
    
    let result: Int = operation() // 컴파일 오류

    올바른 코드:

    let operation: () -> Int = {
        return 5 + 10
    }
    
    let result: Int = operation() // 올바르게 작동

    주의사항: 클로저의 타입을 명시적으로 지정하여 오류를 방지할 수 있습니다.

    6. 정리

    • 클로저는 함수처럼 동작하는 코드 블록으로, 재사용성과 가독성을 높일 수 있습니다.
    • 클로저는 외부 변수를 캡처하고, 비동기 작업에서 유용하게 사용됩니다.
    • 클로저의 사용 예로는 배열 정렬 및 API 비동기 처리 등이 있습니다.
    • 변수를 캡처할 때 주의해야 하며, 타입을 명시적으로 지정하는 것이 좋습니다.
    • 다음에 학습하면 좋은 주제

    • 클로저의 메모리 관리와 강한 참조 vs 약한 참조
    • 클로저를 활용한 고차 함수
    • 클로저의 escaping과 non-escaping 이해하기