클로저 (Closures)

함수를 명명하지 않고 사용할 수 있고, 변수나 상수에 할당하여 사용할 수 있다.
함수가 변수나 상수에 복사되어지는데, 이를 클로저라고 한다.

클로저 생성

이미 정의되어 있는 함수를 변수나 상수에 할당할 수 있다.

//greet라는 함수를 정의
func greet() {
    print("Hello")
}

//상수에 함수를 할당 (클로저)
let greetUser = greet

//클로저를 사용
greetUser()

함수를 할당하는 부분에 괄호()를 붙이지 않았다는 것을 주목해야 한다.
괄호를 붙이면 함수를 할당하는 것이 아닌 함수 호출이 되어버리며,
변수(또는 상수)에 함수의 리턴된 값을 할당한다는 것을 의미하기 때문이다.

let greet = {
    print("Asdf")
}

greet()

클로저 안에 함수를 사용할 수도 있음

매개변수, 리턴값이 있는 클로저

클로저 표현식은 중괄호 {}안에 작성이 되기 때문에, 중괄호 바깥에 매개변수나 리턴값 등을 작성할 수 없다. 이들 역시 중괄호 안에 표기해야 한다.

중괄호 바깥에 매개변수를 작성하는 경우, 클로저의 매개변수가 아닌 튜플을 생성하는 것으로 착각하기 때문이다.

let greet = {
    (name: String) -> String in
    "Hello \(name)!"
}

여는 괄호 다음에 위치한 소괄호()에는 매개변수를 작성한다.
화살표->를 사용하여 함수의 리턴 타입을 명시한다.
in 키워드를 사용하여 다음에 올 표현식들이 클로저의 본문임을 알린다.

함수에 사용할 매개변수가 없고, 리턴타입이 있는 경우는
()->Int와 같은 형식으로 작성한다. (func를 사용한 함수 생성처럼)

void 타입

함수의 타입은 함수가 리턴하는 값의 타입에 따라 달라진다.
void타입은 함수가 리턴하는 값이 없다는 것을 의미한다.

이미 정의된 함수를 복사하여 사용하는 경우 또는 클로저를 정의하는 경우 외부 매개변수의 이름은 사용되지 않는다.
외부 매개변수 이름은 함수를 직접 호출하는 경우에만 고려한다.

예제 : sorted()와 클로저를 사용한 정렬

함수를 다른 함수의 인수로 사용할 수 있다.

sorted(by:)

첫번째 값이 두번째 값보다 앞에 위치해야 한다면 true를, 아닌 경우에는 false를 리턴하는 클로저를 지원한다.
이외의 경우에는 부등호 (< 또는 >)를 사용하여 정렬 방향을 지시할 수 있다.

// 무작위 이름 목록
let randomNames = ["Alice", "Bob", "Charlie", "David", "Ella", "Frank", "Grace", "Hank", "Ivy", "Jack", "Katie", "Liam", "Mia", "Noah", "Olivia", "Peter", "Quinn", "Rachel", "Sam", "Tom", "Uma", "Victor", "Wendy", "Xander", "Yara", "Zane"]


func sortCaptainFirstName(name1: String, name2: String) -> Bool {
    if name1 == "Sam" {
        return true
    } else if name2 == "Sam" {
        return false
    }
            
    // <는 알파벳순 정렬, >는 알파벳 역순 정렬
    return name1 > name2
}

print(randomNames.sorted(by: sortCaptainFirstName))

>>>
["Sam", "Zane", "Yara", "Xander", "Wendy", "Victor", "Uma", "Tom", "Rachel", "Quinn", "Peter", "Olivia", "Noah", "Mia", "Liam", "Katie", "Jack", "Ivy", "Hank", "Grace", "Frank", "Ella", "David", "Charlie", "Bob", "Alice"]

카테고리:

업데이트: