값 캡처
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 및 기타 많은 언어에서도 동일한 기법을 볼 수 있습니다.
챌린지
중급작은 카운터 팩토리를 만드세요.
() -> Int 타입의 클로저를 반환하는 makeCounter(start: Int, step: Int) 함수를 정의하세요. 클로저를 호출할 때마다 다음 값을 반환합니다: 첫 번째 호출은 start를 반환하고, 다음은 start + step, 그 다음은 start + 2*step과 같은 식입니다.
입력에서 세 개의 정수 start, step, n을 읽으세요. start와 step으로 카운터를 생성한 다음, 이를 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번 호출하고 각 결과를 출력하세요
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.