Menu
Coddy logo textTech

값 캡처

Coddy Swift 여정의 로직 및 흐름 섹션에 포함된 레슨 — 56개 중 40번째.

클로저는 생성될 때 스코프 내에 있던 변수들을 기억합니다. 클로저 본문은 나중에, 심지어 자신을 둘러싼 함수가 반환된 후에도 이 변수들을 읽거나 수정할 수 있습니다. 이를 캡처링(capturing)이라고 합니다.

func makeCounter() -> () -> Int {
    var count = 0
    return {
        count += 1
        return count
    }
}

let next = makeCounter()
print(next())                    // 1
print(next())                    // 2
print(next())                    // 3

makeCounter 호출은 완전히 새로운 count를 제공하므로, 두 카운터는 상태를 절대 공유하지 않습니다:

let a = makeCounter()
let b = makeCounter()
print(a())                       // 1
print(b())                       // 1
print(a())                       // 2

캡처링은 클로저를 일반 함수보다 더 강력하게 만드는 요소입니다. 클로저는 상태를 함께 가지고 다니기 때문입니다. JavaScript, Python 및 기타 많은 언어에서도 동일한 기법을 볼 수 있습니다.

challenge icon

챌린지

중급

작은 카운터 팩토리를 만드세요.

() -> Int 타입의 클로저를 반환하는 makeCounter(start: Int, step: Int) 함수를 정의하세요. 클로저를 호출할 때마다 다음 값을 반환합니다: 첫 번째 호출은 start를 반환하고, 다음은 start + step, 그 다음은 start + 2*step과 같은 식입니다.

입력에서 세 개의 정수 start, step, n을 읽으세요. startstep으로 카운터를 생성한 다음, 이를 n번 호출하고 각 결과를 별도의 줄에 출력하세요.

입력 5 / 3 / 4에 대한 출력은 다음과 같습니다:

5
8
11
14

치트 시트

클로저는 주변 범위(scope)에서 변수를 캡처하여, 외부 함수가 반환된 후에도 상태를 유지합니다:

func makeCounter() -> () -> Int {
    var count = 0
    return {
        count += 1
        return count
    }
}

let next = makeCounter()
print(next()) // 1
print(next()) // 2

팩토리 함수를 호출할 때마다 독립적인 캡처 변수가 생성되므로, 두 카운터는 상태를 절대 공유하지 않습니다.

직접 해보기

let start = Int(readLine()!)!
let step = Int(readLine()!)!
let n = Int(readLine()!)!

// TODO: 실행 중인 값을 캡처하는 makeCounter(start:step:) -> () -> Int를 만드세요
// 그런 다음 n번 호출하고 각 결과를 출력하세요
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

로직 및 흐름의 모든 레슨