스터디를 진행하며 처음부터 다시 Swift를 공부하고 있습니다.
오늘 작성할 파트는 클로저 입니다.
org에 있는 클로저 목차는 이해가 좀.. ㅇ ㅓ렵네요..
let closure = { () -> () in
print("Closure")
}
closure() //Closure
클로저는 함수랑 다르게 Argument Label을 사용하지 않습니다.
func closure(number : (Int, Int, Int) -> Int) {
number(1,2,3)
}
이 함수는 파라미터로 받은 클로저를 실행하는데, 클로저의 파라미터로 1,2,3이란 숫자를 넘겨주고 있습니다.
해당 함수를 호출할 때 이런식으로 클로저를 작성 했어야 했습니다.
closure(number : { (a: Int, b: Int, c: Int) -> Int in
return a + b + c
})
여기서 우리는 파라미터 형식과 리턴 형식을 생략할 수 있습니다.
closure(number : { (a, b, c) in
return a + b + c
})
또한 여기서 더 축약이 가능한데, shorthand argument names
를 이용하면 됩니다.
shorthand argument names
는 Parameter Name 대신 사용할 수 있습니다.
a = $0
, b = $1
, c = $2
로 경량화하여 아래처럼 작성이 가능합니다.
closure(number : {
return $0 + $1 + $2
})
해당 예제에서는 클로저 구문에 return 구문 하나기 때문에 return문도 생략이 가능합니다.
단일 return이 아닌데 return을 없애고 그냥 작성한다면 에러가 뜨게 되니 주의!!
closure(number : {
$0 + $1 + $2
})
또한 number 파라미터가 마지막 파라미터라면 트레일링 클로저로 작성할 수 있습니다.
트레일링 클로저란, 마지막 파라미터가 클로저일 때,
이를 파라미터 값 형식이 아닌 함수 뒤에 붙여 작성하는 문법입니다.
이때, Argument Label은 생략됩니다.
만약 ()에 값이 아무것도 없다면 ()도 생략이 가능합니다.
closure {
$0 + $1 + $2
}
따라서 해당 예제는 이렇게까지 축약이 가능합니다.
함수 실행을 벗어나서 함수가 끝난 후에도 클로저를 실행하고 싶을 때 사용
func closure(number : @escaping () -> ()) {
}
이렇게 클로저 파라미터 타입 앞에 @escaping을 붙여주면 됩니다.
non-escaping closure | escaping closure |
---|---|
함수의 실행 흐름을 탈출하지 않아, 함수가 종료되기 전에 무조건 실행 되어야 한다. | 함수 실행을 벗어나서 함수가 끝난 후에도 클로저를 실행하고 싶을 때 사용한다. |
보통 @escaping은 네트워킹(비동기)을/를 할 때 많이 사용됩니다.
네트워킹 로직은 UI 업데이트와 데이터간의 순서가 중요하기에 @escaping이 필요하다고 합니다. ( 자세한 내용은 추후 네트워크를 다룰 때 작성 예정 )
바로 실행되어야 하는 구문이 지연되어 실행
이스케이핑과 마찬가지로 클로저 파라미터 타입 앞에 붙여줍니다.
func closure(number : @autoclosure () -> ()) {
}
이제 closure란 파라미터는 실제 클로저를 전달받지 않지만, 클로저처럼 사용이 가능합니다.
@autoclosure 사용시 파라미터가 반드시 없어야 합니다.
리턴 타입은 상관 없습니다.
+) @autoclosure @escaping 속성을 둘 다 사용할 수도 있다고 합니다..
( 추가예정 )
https://bbiguduk.gitbook.io/swift/
https://babbab2.tistory.com/
https://okanghoon.medium.com/swift-study-1-클로저-고차함수-abe199f22ad8