클로저(Closure)란 ?
클로저란 func 키워드를 이용해 이름을 붙여주는 함수를 모두 일컫습니다.
클로저에는 Named Closure와 Unnamed Closure 두 가지가 있습니다.
1. Named Closure
func namedFunc() {
print("Named Function입니다.")
}
Named Closure는 우리가 여태 선언해왔던 이름이 있는 함수로 클로저라 부르지 않고, 함수라고 부릅니다.
2. Unnamed Closure
let unnamedFunc = {
print("Unnamed Func입니다.")
}
Unnamed Closure는 익명 함수로 보통 클로저라고 하면 Unnamed Closure를 의미합니다.
즉, 클로저는 Named Closure와 Unnamed Closure 둘 다 포함하지만, 보통 익명 함수인 Unnamed Closure를 의미합니다.
클로저 표현식
{ (Parameters) -> Return Type in
// 실행구문
}
- Parameter와 Return Type이 둘 다 없는 클로저
let closure = { () -> () in
print ("Closure입니다.")
}
클로저는 익명이긴 하지만 함수이기 때문에 Swift에서 1급 객체입니다.
그러므로 상수에 클로저를 대입할 수 있습니다.
- Parameter와 Return Type이 둘 다 있는 클로저
let closure = { (name: String) -> String in
return "Hello, \(name)"
}
closure("0inn")
closure(name: "0inn") // error
함수와 비슷해보이지만 Parameter의 name은 단독으로 쓰였으니 " Argument Label이자 Parameter Name이겠다! " 생각할 수 있겠지만, 클로저에서는 Argument Label을 사용하지 않고 오직 Parameter Name만 사용합니다.
Argument Label 이란 ?
func sayHello(to name: String) {
print ("Hello, \(name)")
}
sayHello(to: "0inn")
이 코드에서 to를 Argument Label 이라고 합니다.
클로저의 특징
앞서 말했듯이 클로저는 1급 객체이기 때문에 1급 객체 함수의 특징을 가지고 있습니다.
1. 클로저를 변수나 상수에 대입할 수 있다.
// 대입과 동시에 클로저 작성 가능
let closure = { () -> () in
print("Closure입니다.")
}
// 새로운 변수나 상수에 대입 가능
let newClosure = closure
2. 함수의 파라미터 타입으로 클로저를 전달할 수 있다.
sayHello(closure: { () -> () in
print("Hello")
})
3. 함수의 반환 타입으로 클로저를 사용할 수 있다.
func sayHello() -> () -> () {
return { () -> () in
print("Hello")
}
}
let closure = sayHello()
closure() // Hello
클로저 실행
1. 클로저가 대입된 변수나 상수로 호출
let closure = { () -> String in
return "Hello"
}
closure()
2. 클로저 직접 실행
({ () -> () in
print("Hello")
})()
트레일링 클로저 (Trailing Closure)
트레일링 클로저란 함수의 마지막 파라미터가 클로저일 때 이를 파라미터 값 형식이 아닌 함수 뒤에 붙여 작성하는 문법입니다.
이 때, Argument Label은 생략됩니다.
1. 파라미터가 클로저 하나인 함수
func sayHello(closure: () -> ()) {
closure()
}
// inline Closure 호출 방식
sayHello(closure: { () -> () in
print("Hello")
})
// trailing Closure 호출 방식
sayHello () { () -> () in
print("Hello")
}
// 파라미터 하나일 경우 () 생략 가능
sayHello() { () -> () in
print("Hello")
}
- 파라미터가 클로저 하나일 경우, 마지막 파라미터이므로 트레일링 클로저 가능
- closure라는 Argument Label은 트레일링 클로저에서 생략
2. 파라미터가 여러 개인 함수
func fetchData(success: () -> (), fail: () -> ()) {
}
// inline Closure
fetchData(success: { () -> () in
print("Success")
}, fail: { () -> () in
print("Fail")
})
// Trailing Closure
fetchData(success: { () -> () in
print("Success")
}) { () -> () in
print("Fail")
}
클로저 경량 문법
func plus(closure: (Int, Int, Int) -> Int) {
closure(1, 2, 3)
}
// inline Closure
plus(closure: { (a: Int, b: Int, c: Int) -> Int in
return a + b + c
})
inline Closure 방식을 경량 문법으로 간단하게 바꿔보자 !
1. 파라미터 형식과 리턴 형식 생략 가능
plus(closure: (a, b, c) in
return a + b + c
})
2. Parameter Name은 Shortand Argument Names으로 대체하고, 이 경우 Parameter Name과 in 키워드를 삭제
Parameter Name : a, b ,c
Shortand Argument Names : $0, $1, $2
plus(closure: {
return $0 + $1 + $2
})
3. 단일 리턴문만 남을 경우, return 생략
단일 리턴문이란 ?
클로저 내부에 코드가 return 구문 하나만 남은 경우
plus(closure: {
$0 + $1 + $2
})
4. 클로저 파라미터가 마지막 파라미터면 트레일링 클로저로 작성
plus() {
$0 + $1 + $2
}
5. ()에 값이 아무것도 없다면 생략
plus {
$0 + $1 + $2
}
결론적으로 이렇게 간단하게 클로저를 사용할 수 있습니다 !
참고
https://babbab2.tistory.com/81?category=828998
'iOS > Swift' 카테고리의 다른 글
[Swift] stride 함수 / Set (0) | 2022.10.25 |
---|---|
[Swift] Swift 알고리즘 - 수학 (0) | 2022.10.13 |
[Swift] Swift 알고리즘 - Dictionary (0) | 2022.10.12 |
[Swift] Swift 알고리즘 - 문자열 / 배열 (0) | 2022.10.11 |
[Swift] Class vs. Struct vs. Enum (0) | 2022.09.06 |