안녕하세요:)
오늘은 익명 코드 블록을 구현하는 방법인 Closure를 알아보도록 하겠습니다.
{ (parameters) -> ReturnType in
statements
}
{ statements } // 가장 단순한 클로저 표현식
let a = { print("Hello, blog") }
a() // Hello, blog
// 파라미터와 리턴형이 있는 클로저
let a2 = { (str: String) -> String in
return "Hello, \(str)" // str은 파라미터 이름입니다.
}
let call = a2("blog")
print(call) // Hello, blog
// 클로저를 파라미터로 전달
typealias strClosure = (String) -> (String)
func printHello(closure: strClosure) {
print(closure("iOS"))
}
printHello { (str: String) -> (String) in
return "Hi, \(str)"
} // Hi, iOS
불필요한 요소를 생략하고 단순하게 작성하는 것을 문법 최적화라고 합니다.
let appleProduct = ["iPhone Pro", "ipad Pro", "Air Pod Pro", "MacBook Pro", "MacBook Air", "iMac Pro",
"iMac", "iPhone", "iPod"
]
var ProModels = appleProduct.filter( { (name: String) -> Bool in
return name.contains("Pro")
})
ProModels = appleProduct.filter( {
return name.contains("Pro")
}) // 1
ProModels = appleProduct.filter( {
return $0.contains("Pro")
}) // 2
ProModels = appleProduct.filter( {
$0.contains("Pro")
}) // 3
ProModels = appleProduct.filter() { $0.contains("Pro") } // 4
ProModels = appleProduct.filter { $0.contains("Pro") } // 5
클로저 표현식으로 작성한 클로저는 외부에 있는 값에 접근할 때 값을 캡처합니다.
var num = 0
print("check point #1: \(num)") // check point #1: 0
num += 1
print("check point #2: \(num)") // check point #2: 1
num = 0 // 초기화
let a1 = {
num += 1
print("check point #3: \(num)")
}
a1() // check point #3: 1
print("check point #4: \(num)") // check point #4: 1
func nonEscaping(closure: () -> ()) {
print("Start")
closure()
print("End")
}
nonEscaping {
print("closure")
} // Start -> closure -> End
func Escaping(closure: @escaping () -> ()) {
print("START")
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
closure()
}
print("END")
}
Escaping {
print("CLOSURE")
} // START -> END -> CLOSURE