- 일회용 함수를 작성할 수 있는 구문
- 익명 함수라고도 부름
일회용 함수는 한 번만 사용하면 되므로 굳이 함수의 이름을 작성할 필요가 없다
{ (매개변수) -> 변환타입 in
//실행할 구문
}
예시를 이용하여 알아봅시다
📚 배열 하나를 작성해 보겠음
var value = [1,9,5,7,3,2]
이 배열을 정렬 함수 sort(by:)를 이용하여 정렬해 보자.
정렬 기준을 위해 함수를 정의하여 인자값으로 넣어주어야 한다.
📚 함수를 작성하여 sort(by:) 메서드의 인자로 넣기
func order(s1: Int, s2: Int) -> Bool {
if s1 > s2 { //s1이 s2보다 클 경우 true 리턴
return true
} else {
return false
}
}
value.sort(by: order) // 9 7 5 3 2 1
📚 order을 클로저 형식으로 표현해 보기
{
(s1: Int, s2: Int) -> Bool in
if s1 > s2 {
return true
} else {
return false
}
}
📚 order의 클로저 표현식을 sort 메서드의 인자값으로 사용해 보기
value.sort(by: {
(s1: Int, s2: Int) -> Bool in
if s1 > s2 {
return true
} else {
return false
}
})
📚 클로저 표현식을 좀 더 간단하게 만들어 보기
{ (s1: Int, s2: Int) -> Bool in return s1>s2 }
value.sort(by: { (s1: Int, s2: Int) -> Bool in
return s1>s2
})
❗️클로저 표현식은 반환값 타입을 생략할 수 있음 -> 컴파일러가 클로저 표현식의 구문을 해석하여, 반환타입을 추론한다
{ (s1: Int, s2: Int) in return s1>s2}
value.sort(by: { (s1: Int, s2: Int) in
return s1>s2
})
❗️매개변수의 타입 정의를 생략할 수 있음 -> 마찬가지로 컴파일러가 추론 가능
{ s1, s2 in return s1>s2 }
value.sort(by: { s1, s2 in
return s1>s2
})
❗️매개변수도 생략이 가능하고, in 키워드 역시 생략 가능 -> 매개변수명 대신 $0, $1... 와 같은 이름으로 할당된 내부 상수를 이용. 입력받은 인자값의 순서대로 매칭됨
{ return $0>$1 }
value.sort(by: {
return $0>$1
})
❗️ 클로저가 반환하는 값이 있다면, return 키워드도 생략 가능 -> 클로저의 마지막 줄의 결과값은 암시적으로 반환값으로 취급
{ $0>$1 }
value.sort(by: {
$0>$1
})
- trailing: 후행
- 함수의 마지막 인자값이 클로저일 때, 이를 인자값 형식으로 작성하는 대신 함수의 뒤에 꼬리처럼 붙일 수 있는 문법
- 함수의 마지막 인자값에만 적용!!!!!!!!!!
- 인자 레이블은 생략
📚 인자값으로 사용되던 클로저를 통째로 밖으로 꺼낸 뒤, sort() 메서드 뒤쪽에 붙임
value.sort() { (s1, s2) in
return s1 > s2
}
📚 인자값이 하나일 경우, sort 뒤의 괄호 생략 가능 -> 더 필요한 인자값도 없고, 호출 구문임이 명확하므로 괄호를 쓰지 않아도 됨!
value.sort { (s1, s2) in
return s1 > s2
}
- 인자값들이 모두 클로저여도, 트레일링 클로저 문법은 마지막 인자값에만 적용
- Swift에서 함수의 인자값으로 전달된 클로저는 기본적으로 탈출 불가(non-escape)
- 탈출 불가로 관리함으로써 컴파일러가 메모리 관리상 지저분한 일들에 관여할 필요가 없음 -> 성능 향상
- 이는 해당 클로저는 함수 내에서 혹은 직접 실행을 위해서만 사용 가능하다는 것을 의미
- 변수나 상수에 대입할 수 없다 (함수 내부여도)
- @escaping 속성을 클로저에 붙여주면, 해당 클로저는 탈출 가능하다
- @escaping 속성은 함수 타입 정의 앞에 넣어줌
- 인자값으로 전달된 일반 구문이나 함수 등을 클로저로 wrapping
- 일반 구문을 인자값으로 넣으면, 컴파일러가 알아서 클로저로 사용함
- 인자값이 {} 형태가 아니라, () 형태로 사용 가능
- 따라서 코드를 이해하기 쉬운 형태로 만들어 준다
- @autoclousre 속성도 함수 타입 정의 앞에 넣어줌
아직 @escaping과 @autoclosure 속성을 사용해 보지 못해서 감이 잘 안 잡히는 중...
키워드를 사용하게 된다면 따로 포스팅해 보겠습니당.
출처)
꼼꼼한 재은씨의 Swift: 문법편