이번 내용은 클로저에 관한 내용이다. 책으로만 읽었을 때는 감이 잘 안와서, 여러 영상과 블로그를 찾아보고 나름대로 정리한 것이다.
스위프트는 객체 지향형 프로그래밍에 함수형 프로그래밍 패러다임을 더한 언어이다. 함수형 프로그래밍 패러다임 중 가장 먼저 알아야 하고, 스위프트를 배운다면 무조건 마주치게 될 것이 바로 '클로저'이다.
클로저는 어떤 테스크를 수행하기 위한 코드 블록을 말한다. 그럼 함수랑 다른 점이 있는가? 라고 생각을 해보면 사실 함수가 클로저의 일부이다 !
이름 있는 클로저 -> 함수
이름 없는 클로저 -> 일반적으로 클로저라고 부르는 형태
클로저는 매개변수와 반환 값의 타입을 생략할 수 있음
{ (parameters) -> return type in
statements
}
let checking = { print("checking!!") }
checking() //checking!!
let checking = { (id: String) in //파라미터를 받을 수 있음
print("checking id: \(id)")
}
checking("User1") //checking id: User1
let checking = { (id: String) -> Bool in //리턴값 존재
if id == "User1" {
return false
}
return true
}
let isValid = checking("User2") //true
let isValid = checking("User1") //false
func validate(id: String, checking: (String) -> Bool) -> Bool { //위에 작성한 checking 클로저를 파라미터로 사용함
let isValid = checking(id)
return isValid
}
let validationResult = validate(id: "User2", checking: checking) //true (리턴 값이 true임)
let validationResult2 = validate(id: "User1", checking: { (id: String) -> Bool in
if id == "User0" {
return false
}
return true
}) //checking에 대한 클로저를 따로 정의하지 않고, 함수 안에서 만들었음
doSomeClosure ({ print("Hello World") } // 클로저를 안에서 만들고 바로 사용
클로저 표현 간소화
종류
let validationResult = validate(id: "User0", checking: { (id: String) -> Bool in
if id == "User1" {
return false
}
return true
})
let validationResult2 = validate(id: "User1", checking: { id in //클로저 선언부를 줄일 수 있음 (return이 있기 때문에 스위프트에서 알아서 추론함)
if id == "User0" {
return false
}
return true
})
let validationResult3 = validate(id: "User1", checking: { id in //if문을 리팩토링함
let isValide = id != "User0"
return isValid
})
let validationResult4 = validate(id: "User1", checking: { $0 != "User0" }) //$0, $1, ... : 클로저로 들어오는 input을 나타냄
let validationResult5 = validate(id: "User1") { $0 != "User0" } //trailing closure: 맨 마지막에 들어오는 클로저는 파라미터를 작성하지 않아도 됨
값 획득
참조 타입
탈출 클로저 (@escaping)
var sampleClosure: () -> Void = { }
func callback(closure: @escaping() -> Void) { //만약 @escaping이 없다면 에러 발생
sampleClosure = closure
sampleClosure()
}