HIT해

[Swift 기초문법 -10] Closer 본문

Swift/Swift 기초문법

[Swift 기초문법 -10] Closer

힛해 2024. 7. 11. 02:17
728x90

Swift에서 클로저란 무엇인가?

클로저(Closure)는 코드에서 일급 시민(First-class Citizen)으로 취급되는 독립적인 코드 블록이다.

클로저는 특정한 기능을 수행하는 코드를 캡슐화하여 변수나 상수에 저장하거나, 다른 함수에 인자로 전달할 수 있습니다.

Swift의 클로저는 다른 언어에서의 람다(lambda)나 익명 함수(anonymous function)와 유사합니다.

 

정리하자면 클로저 자체는 그냥 메소드를 실행하는 것인데 함수와 다르게 클로저로 선언한 이름을 그대로 사용하면 된다.

 

기본적인 문법은 아래와 같다!

{ (매개변수들) -> 반환형 in
    실행할 코드
}

 

사용하는 예시를 보자

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

let result = add(3, 5) // result는 8

 

함수가 아닌데 함수처럼 사용할 수 있다!

 

반환값을 따로 두고 싶지 않다면 이렇게 활용도 가능하다

let add: (Int, Int) -> Void = { (a: Int, b: Int) in
	var result = a+b
    print("\(result)"
}

add(3, 5) // 8출력

 

클로저의 간소화

Swift에서는 클로저의 문법을 간결하게 하기 위해 여러 가지 생략을 허용한다!

예를 들어, 클로저의 타입을 추론할 수 있는 경우 매개변수와 반환형을 생략할 수 있다!

1. 매개변수와 반환형 생략

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

2. 단일 표현식 클로저의 암시적 반환

클로저가 단일 표현식을 포함하는 경우 return 키워드를 생략할 수 있다!

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

3. 매개변수 이름 축약

Swift는 $0, $1 등의 축약된 매개변수 이름을 제공한다!

let add: (Int, Int) -> Int = {
    $0 + $1
}

 

함수를 사용하지 않고 왜 클로저를 사용하지?

함수와 클로저는 많은 면에서 유사하지만, 클로저는 몇 가지 독특한 장점을 가지고 있다.

다음은 함수와 클로저를 비교하고, 클로저가 더 유용한 상황을 설명하는 몇 가지 예시다!

함수와 클로저 비교

이름 유무

- 함수는 이름을 가진다.

- 클로저는 이름이 없고, 코드 블록 자체가 독립적으로 존재할 수 있다!

문맥 캡처

- 함수는 특정 문맥을 캡처하지 않는다.

- 클로저는 자신이 정의된 문맥의 변수나 상수를 캡처할 수 있다. 이를 통해 클로저는 외부 변수의 상태를 저장하고 변경할 수 있다!

간결함

- 함수는 일반적으로 더 길고 형식적인 선언이 필요하다.

- 클로저는 간결한 문법을 제공하여 코드의 가독성을 높일 수 있다!

 

클로저의 장점

고차 함수와의 통합

클로저는 고차 함수(higher-order function)와 함께 사용하기에 매우 적합하다.

예를 들어, map, filter, reduce와 같은 함수형 프로그래밍 패턴에서 클로저를 사용하면 코드가 더 간결하고 읽기 쉬워진다!

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

 

비동기 작업

클로저는 비동기 작업을 처리할 때 유용하다.

예를 들어, 네트워크 요청이 완료된 후 특정 작업을 수행해야 할 때 클로저를 콜백으로 사용할 수 있다!

func fetchData(completion: @escaping (Data?, Error?) -> Void) {
    // 네트워크 요청 코드
    // 요청이 완료되면 completion 클로저 호출
}

fetchData { data, error in
    if let data = data {
        // 데이터를 처리하는 코드
    } else if let error = error {
        // 에러를 처리하는 코드
    }
}

 

문맥 캡처

클로저는 외부 변수나 상수를 캡처할 수 있어, 함수 내부에서 외부 상태를 유지하거나 변경하는 데 유용하다!

func makeIncrementer(incrementAmount: Int) -> () -> Int {
    var total = 0
    let incrementer: () -> Int = {
        total += incrementAmount
        return total
    }
    return incrementer
}

let incrementByTwo = makeIncrementer(incrementAmount: 2)
print(incrementByTwo()) // 2
print(incrementByTwo()) // 4

 

클로저 매력적인 문법이다..