-
클로저
클로저란, 자신이 정의되었던 문맥(Context)으로부터 모든 상수와 변수의 값을 캡처하거나 레퍼런스를 저장하는 익명 함수이다.
- 전역 함수
이름이 있으며, 주변 환경에서 캡처할 어떤 값도 없는 클로저 - 중첩 함수
이름이 있으며 자신을 둘러싼 함수(내부 함수)로부터 캡처할 값이 있는 클로저 - 클로저 표현식
이름이 없으며 주변 환경으로부터 값을 캡처할 수 있는 경량 문법으로 작성된 클로저
클로저 포현식은 간단하게 줄일 수 있다.
let c = { (s1: Int, s2: String) -> Void in print("s1: \(s1), s2: \(s2)") } c(1, "closure")
위의 식을 아래와 같이 줄일 수 있다.
({ (s1: Int, s2: String) -> Void inn print("s1: \(s1), s2: \(s2)") })(1, "closure")
클로저를 작성할 때는 간결성과 가독성의 비율을 항상 고려해야 한다.
클로저 표현식과 경량 문법
var value = [1, 9, 5, 7, 3, 2] func order(s1: Int, s2: Int) -> Bool { if s1 > s2 { return true } else { return false } } value.sort(by: order)
위와 같은 order 함수를 클로저 표현식으로 바꾸어 아래에 작성해보았다.
value.sort(by: { (s1: Int, s2: Int) -> Bool in if s1 > s2 { return true } else { return false } })
위와 같은 클로저 표현식은 여러 형태로 간결화할 수 있다.
value.sort(by: { (s1: Int, s2: Int) -> Bool in return s1 > s2 })
if문을 간결화할 수 있고
value.sort(by: { (s1: Int, s2: Int) in return s1 > s2 })
반환 값 타입을 컴파일러가 추론하게 맡길 수도 있다.
value.sort(by: { s1, s2 in return s1 > s2 })
이렇게 간결화되다 보면
value.sort(by: { $0 > $1 }) value.sort(by: >)
최종적으로 이렇게 간결화될 수 있다.
부등 비교 연산자는 원래 두 개의 인자가 필요하고, 이를 첫 번째 인자와 두 번째 인자로 해석한다면 비교 연산자 하나만으로 함수처럼 표현할 수 있기 때문에 위와 같은 표현이 가능해진다.
트레일링 클로저(Trailing Closure)
여러 줄로 작성된 코드가 함수의 인자 값으로 전달될 때는 아무리 깔끔하더라도 가독성이 떨어진다는 문제가 있다.
그렇기 때문에 함수의 마지막 인자 값이 클로저일 때, 이를 함수의 뒤에 꼬리처럼 붙일 수 있는 문법이 트레일링 클로저이다.
(반드시 마지막 인자 값에만 적용된다)
func divide(base: Int, success s: () -> Void) -> Int { defer { s() // 성공 함수를 실행한다. } return 100 / base }
이 함수는 현재 두 개의 인자 값을 입력받는데, 첫 번째는 Int 타입의 값이고, 두 번째는 연산 성공 시 실행할 함수 또는 클로저이다.
마지막 값에 클로저를 넣을 수 있으므로 위 함수는 트레일링 클로저를 사용할 수 있는 조건이 충족된다.
divide(base: 100) { () in print("연산이 성공했습니다.") }
트레일링 클로저를 사용하여 divide 함수를 호출하는 구문이다.
divide 함수는 첫 번째 인자 값으로 Int 타입의 정수를 입력받아야 하므로, 괄호를 완전히 생략할 수는 없다.
대신 두 번째 인자 값에 대한 레이블인 "success:"는 생략 가능하다.
어쨌든 인자 값이 하나 이상이라면 괄호를 생략할 수 없다. 오직 마지막 인자 값만 생략이 가능하다.
'iOS > Swift' 카테고리의 다른 글
[Swift] ARC 알아보기 (Auto Reference Counting) (0) 2020.09.04 Closure (2) (0) 2020.04.17 프로토콜 지향언어, Swift (3) (0) 2020.03.21 프로토콜 지향언어, Swift (2) (1) 2020.03.14 프로토콜지향 언어, Swift (1) (0) 2020.03.07 - 전역 함수