UIView.animate(withDuration:animations:completion)
와 같은 메소드를 사용할 경우 함수의 이름 없이 본문만 전달할 수 있다면 매우 편리할 것이다. 이는 익명 함수(anonymous function)을 이용하면 가능하다. 익명 함수는 이름이 없는 함수 본문을 말한다.
{}
)로 감싼다.in
키워드와 함께 적는다.// 익명 함수 만드는 예시
func whatToAnimate() {
self.myButton.frame.origin.y += 20
}
{
() -> () in
self.myButton.frame.origin.y += 20
}
func whatToDoLater(finished: Bool) {
print("finished: \(finished)")
}
{
(finished: Bool) -> () in
print("finished: \(finished)")
}
익명 함수는 함수의 인자에서 바로 사용할 수 있다.
UIView.animate(withDuration: 0.4,
animations: {
() -> () in
self.myButton.frame.origin.y += 20
},
completion: {
(finished: Bool) -> () in
print("finished: \(finished)")
}
}
익명 함수는 스위프트에서 매우 자주 사용되고 중요하기 때문에 익명함수를 간단하게 작성할 수 있는 방법이 제공된다.
컴파일러가 익명 함수의 리턴 타입을 이미 알고 있다면 ->
와 리턴 타입을 생략할 수 있다.
UIView.animate(withDuration: 0.4,
animations: {
() in
self.myButton.frame.origin.y += 20
},
completion: {
(finished: Bool) -> () in
print("finished: \(finished)")
}
}
in
생략익명 함수가 파라미터가 없고 리턴 타입을 생략할 수 있는 경우에는 in
키워드도 생략할 수 있다.
UIView.animate(withDuration: 0.4,
animations: {
self.myButton.frame.origin.y += 20
},
completion: {
(finished: Bool) -> () in
print("finished: \(finished)")
}
}
컴파일러가 익명 함수의 파라미터를 알고 있다면 파라미터 타입을 생략할 수 있다.
UIView.animate(withDuration: 0.4,
animations: {
self.myButton.frame.origin.y += 20
},
completion: {
(finished) in
print("finished: \(finished)")
}
}
파라미터 타입이 생략되었다면 파라미터 목록을 감싸는 괄호를 생략할 수 있다.
UIView.animate(withDuration: 0.4,
animations: {
self.myButton.frame.origin.y += 20
},
completion: {
finished in
print("finished: \(finished)")
}
}
in
생략 ($0, $1, …)리턴 타입이 생략될 수 있고 컴파일러가 파라미터 타입을 알고 있는 경우 in
키워드를 생략하고 익명 함수 본문 내에서 $0
, $1
등을 사용해서 파라미터를 직접 참조할 수 있다.
UIView.animate(withDuration: 0.4,
animations: {
self.myButton.frame.origin.y += 20
},
completion: {
print("finished: \($0)")
}
}
익명 함수의 본문에서 파라미터가 사용되지 않는 경우 파라미터 목록을 _
키워드로 대체할 수 있다.
UIView.animate(withDuration: 0.4,
animations: {
self.myButton.frame.origin.y += 20
},
completion: {
_ in
print("finished: \(finished)")
}
}
in
표현식을 생략하고 $0, $1 등을 사용하거나 in
표현식과 그대로 두고 파라미터 이름을 표시하거나 _
로 파라미터 이름을 생략할 수 있다. 하지만 **in
표현식을 생략하지 않고** $0처럼 파라미터를 표현할 수 없다. 이는 컴파일이 되지 않는다.
익명 함수가 호출되는 함수의 마지막 인자로 오는 경우, 마지막 인자 전에 함수 호출문을 )
로 닫고 그 다음 라벨을 붙이지 않고 익명 함수를 바로 넣을 수 있다. 이는 trailing closure(후행 클로저) syntax라고 한다.
UIView.animate(withDuration: 0.4,
animations: {
self.myButton.frame.origin.y += 20
}) {
_ in
print("finished: \(finished)")
}
스위프트 5.3 이후부터는 여러 개의 익명 함수 인자들에 후행 클로저 문법을 적용할 수 있다.
UIView.animate(withDuration: 0.4) {
self.myButton.frame.origin.y += 20
} completion: {
_ in
print("finished: \(finished)")
}
이때 첫 번째 익명 함수는 라벨이 없지만 남은 함수들은 ,
없이 라벨을 붙여주어야 한다.
후행 클로저를 사용하고 호출하는 함수가 전달하는 함수 외에 매개 변수를 사용하지 않는 경우 호출시 빈 괄호를 생략할 수 있다. 이는 함수 호출에서 괄호를 생략하는 유일한 경우이다.
func doThis(_ f:() -> ()) {
f()
}
doThis {
print("Howdy")
}
return
키워드 생략익명 함수의 본문이 return
키워드를 포함해서 값을 반환하는 문장 하나로만 이루어져 있는 경우, return
키워드를 생략할 수 있다.
func greeting() -> String {
return "Howdy"
}
func performAndPrint(_ f:() -> String) {
let s = f()
print(s)
}
performAndPrint {
greeting() // return greeting()
}