2. Functions (3) - 익명함수

Seoyoung Lee·2022년 7월 10일
0
post-thumbnail
post-custom-banner

UIView.animate(withDuration:animations:completion) 와 같은 메소드를 사용할 경우 함수의 이름 없이 본문만 전달할 수 있다면 매우 편리할 것이다. 이는 익명 함수(anonymous function)을 이용하면 가능하다. 익명 함수는 이름이 없는 함수 본문을 말한다.

익명 함수 만들기

  1. 함수 본문을 함수 선언 없이 중괄호({})로 감싼다.
  2. 필요하다면 함수의 파라미터 목록과 반환 값을 중괄호의 맨 첫 줄에 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)")
}

Using Anonymous Functions Inline

익명 함수는 함수의 인자에서 바로 사용할 수 있다.

UIView.animate(withDuration: 0.4,
	animations: {
		() -> () in
		self.myButton.frame.origin.y += 20
	},
	completion: {
		(finished: Bool) -> () in
		print("finished: \(finished)")
	}
}

Anonymous Function Abbreviated Syntax

익명 함수는 스위프트에서 매우 자주 사용되고 중요하기 때문에 익명함수를 간단하게 작성할 수 있는 방법이 제공된다.

1️⃣ return type 생략

컴파일러가 익명 함수의 리턴 타입을 이미 알고 있다면 -> 와 리턴 타입을 생략할 수 있다.

UIView.animate(withDuration: 0.4,
	animations: {
		() in
		self.myButton.frame.origin.y += 20
	},
	completion: {
		(finished: Bool) -> () in
		print("finished: \(finished)")
	}
}

2️⃣ 파라미터가 없을 때 in 생략

익명 함수가 파라미터가 없고 리턴 타입을 생략할 수 있는 경우에는 in 키워드도 생략할 수 있다.

UIView.animate(withDuration: 0.4,
	animations: {
		self.myButton.frame.origin.y += 20
	},
	completion: {
		(finished: Bool) -> () in
		print("finished: \(finished)")
	}
}

3️⃣ 파라미터 타입 생략

컴파일러가 익명 함수의 파라미터를 알고 있다면 파라미터 타입을 생략할 수 있다.

UIView.animate(withDuration: 0.4,
	animations: {
		self.myButton.frame.origin.y += 20
	},
	completion: {
		(finished) in
		print("finished: \(finished)")
	}
}

4️⃣ 괄호 생략

파라미터 타입이 생략되었다면 파라미터 목록을 감싸는 괄호를 생략할 수 있다.

UIView.animate(withDuration: 0.4,
	animations: {
		self.myButton.frame.origin.y += 20
	},
	completion: {
		finished in
		print("finished: \(finished)")
	}
}

5️⃣ 파라미터가 있는 경우 in 생략 ($0, $1, …)

리턴 타입이 생략될 수 있고 컴파일러가 파라미터 타입을 알고 있는 경우 in 키워드를 생략하고 익명 함수 본문 내에서 $0 , $1 등을 사용해서 파라미터를 직접 참조할 수 있다.

UIView.animate(withDuration: 0.4,
	animations: {
		self.myButton.frame.origin.y += 20
	},
	completion: {
		print("finished: \($0)")
	}
}

6️⃣ 파라미터 이름 생략

익명 함수의 본문에서 파라미터가 사용되지 않는 경우 파라미터 목록을 _ 키워드로 대체할 수 있다.

UIView.animate(withDuration: 0.4,
	animations: {
		self.myButton.frame.origin.y += 20
	},
	completion: {
		_ in
		print("finished: \(finished)")
	}
}

in 표현식을 생략하고 $0, $1 등을 사용하거나 in 표현식과 그대로 두고 파라미터 이름을 표시하거나 _ 로 파라미터 이름을 생략할 수 있다. 하지만 **in 표현식을 생략하지 않고** $0처럼 파라미터를 표현할 수 없다. 이는 컴파일이 되지 않는다.

7️⃣ 함수 argument label 생략

익명 함수가 호출되는 함수의 마지막 인자로 오는 경우, 마지막 인자 전에 함수 호출문을 ) 로 닫고 그 다음 라벨을 붙이지 않고 익명 함수를 바로 넣을 수 있다. 이는 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)")
}

이때 첫 번째 익명 함수는 라벨이 없지만 남은 함수들은 , 없이 라벨을 붙여주어야 한다.

8️⃣ 호출하는 함수의 괄호 생략

후행 클로저를 사용하고 호출하는 함수가 전달하는 함수 외에 매개 변수를 사용하지 않는 경우 호출시 빈 괄호를 생략할 수 있다. 이는 함수 호출에서 괄호를 생략하는 유일한 경우이다.

func doThis(_ f:() -> ()) {
	f()
}
doThis {
	print("Howdy")
}

9️⃣ return 키워드 생략

익명 함수의 본문이 return 키워드를 포함해서 값을 반환하는 문장 하나로만 이루어져 있는 경우, return 키워드를 생략할 수 있다.

func greeting() -> String {
	return "Howdy"
}
func performAndPrint(_ f:() -> String) {
	let s = f()
	print(s)
}
performAndPrint {
	greeting() // return greeting()
}
profile
나의 내일은 파래 🐳
post-custom-banner

0개의 댓글