클로저
//값 캡처
func makeIncrementer(forIncrement amout: Int) -> () -> Int{
var total = 0
//클로저를 반환
let incrementer: () -> Int = {
// total 변수를 캡처하여 저장
total += amount
return total
}
return incrementer
}
let incrementByTen = makeIncrementer(forIncrement: 10)
print(incrementByTen()) // total = 10, 결과: 10
print(incrementByTen()) // total = 20, 결과: 20
---------------------------------------------------------------------------
//참조 캡처
class SimpleClass {
var value: Int = 10
}
func createClosure() -> (() -> Int) {
let instance = SimpleClass()
//참조 캡처를 사용하여 SimpleClass의 인스턴스를 캡처
let closure: () -> Int = {
// 클로저가 참조하는 인스턴스의 속성을 업데이트
instance.value *= 2
return instance.value
}
return closure
}
//클로저 생성
let myClosure = createClosure()
print(myClosure()) // 20
print(myClosure()) // 40
// 클로저 내부에서 참조된 인스턴스의 속성을 변경하였으므로 원본에도 영향을 준다
클로저를 사용하는 이유?
1. 일반적으로 기능을 저장하기 위함
2. 주로 비동기 처리가 필요할 때 사용하는 코드 블록
3. 클래스와 마찬가지로 참조 타입임
예시코드
{ (parameters) -> return type in
// 구현 코드
}
// 함수와 클로저 비교
func pay(user: String, amount: Int){
// function code
}
let payment = {(user: String, amount: Int) in
// closure code
}
파라미터 생략 등 간소화 문법
// 함수의 정의
func performClosure(param: (String) -> Int) {
param("Swift")
}
// 문법을 최적화 하는 과정
// 1) 타입 추론
performClosure(param: { (str: String) in
return str.count // 출력: 5
})
performClosure(param: { str in
return str.count
})
// 2) 한줄인 경우, 리턴을 생략해도 됨(Implicit Return)
performClosure(param: { str in
str.count
})
// 3) 아큐먼트 이름을 축약(Shorthand Argements)
performClosure(param: {
$0.count
})
// 4) 트레일링 클로저
// $0 의 의미: 첫 번째 파라미터를 의미함. (str)
performClosure(param: {
$0.count
})
performClosure() {
$0.count
}
performClosure { $0.count }