swift 기본문법 - 클로저(Closure)

|

개인공부 후 자료를 남기기 위한 목적임으로 내용 상에 오류가 있을 수 있습니다.
인프런, 야곰의 스위프트 기본문법 강좌를 듣고 정리하였습니다.


클로저(Closure)

코드의 블럭으로 일급시민(first-citizen)이다.
일급 객체란 전달 인자로 보낼 수 있고, 변수/상수 등으로 저장하거나 전달할 수 있으며, 함수의 반환 값이 될 수도 있습니다.

따라서 변수, 상수등으로 저장, 전달인자로 전달이 가능하다. 함수의 경우 클로저의 일종으로 이름이 있는 클로저이다.

{ (매개변수 목록) -> 반환타입 in
  실행 코드
}

예시는 아래와 같다.

func sumFunction(a: Int, b:Int) -> Int {
  return a + b
}

var sumResult: Int = sumFunction(a:1, b:2)
print(sumResult)  // 3

// 위 코드를 클로저를 이용해 나타내본다.
var sum: (Int, Int) -> Int = {(a: Int, b:Int) -> Int in return a + b}
sumResult = sum(1,2)
print(sumResult)  // 3

함수는 클로저의 일종으로 sum 변수에는 당연히 함수도 할당할 수 있다.

sum = sumFunction(a:b:)

sumResult = sum(1,2)
print(sumResult)  // 3

함수의 전달인자로서의 클로저

let add: (Int, Int) -> Int
add = {(a: Int, b:Int) -> Int in return a + b}

let substract: (Int, Int) -> Int
substract = {(a:Int, b:Int) -> Int in return a - b}

let divide: (Int, Int) -> Int
divide = {(a:Int, b:Int) -> Int in return a / b}

func calculate(a: Int, b: Int, method: (Int, Int) -> Int) -> Int { return method(a,b ) }

var calculated: Int

calculated = calculate(a: 50, b: 20, method: add)
print(calculated)  // 70

calculated = calculate(a:50, b:20, method: substract)
print(calculated)  // 40

calculated = calculate(a:50, b:25, method: divide)
print(calculated)  // 2

calculated = calculate(a:50, b:10, method: { (left: Int, right: Int) -> Int in return left * right })
print(calculated)  // 500

클로저 고급

너무 다양한 표현법이 있기 떄문에, 적당한 축약 문법어를 사용해야 한다.

  • 후행 클로저
  • 반환타입 생략
  • 단축 인자이름
  • 암시적 반환 표현
func calculate(a:Int, b:Int, method: (Int, Int) -> Int) -> Int {
  return method(a, b)
}

method라는 이름으로 클로저를 전달받는 함수

후행 클로저

클로저가 함수의 마지막 전달인자라면 마지막 매개변수 이름을 생략한 후 함수 소괄호 외부에 클로저를 구현할 수 있다.

result = calculate(a: 10, b:10) {(left: Int, right: Int) -> Int in return left + right }
print(result)  // 20

반환타입 생략

calculate 함수의 method 매개변수는 Int 타입을 반환할 것이라는 사실을 컴파일러도 알기 때문에 굳이 클로저에서 반환타입을 명시해 주지 않아도 된다. 대신 in 키워드는 생략할 수 없다.

result = calculate(a:10, b:10, method: {(left: Int, right: Int) in return left + right })
print(result)  // 20

// 후행 클로저와 같이 사용 가능하다.

result2 = calculate(a:10, b:10) {(left: Int, right: Int) in return left + right }
print(result2)  // 20

단축 인자이름

클로저의 매개변수 이름이 굳이 불필요하다면 단축 인자이름을 활용할 수 있다.
단축 인자이름은 클로저의 매개변수의 순서대로 $0, $1… 처럼 사용 가능하다.

result = calculate(a: 10, b:10, method: { return $0 + $1 })
print(result)  // 20

// 후행 클로저와 같이 사용 가능하다.
result2 = calculate(a:10, b:10) {return $0 + $1}
print(result2)  // 20

암시적 반환 표현

클로저가 반환하는 값이 있다면 클로저의 마지막 줄의 결과값은 암시적으로 반환값으로 취급한다.

result = calculate(a: 10, b: 10) { $0 + $1 }
print(result)  // 20