study record

[Swift] 스위프트 프로그래밍 - 클로저 본문

Swift/스위프트 프로그래밍

[Swift] 스위프트 프로그래밍 - 클로저

asong 2021. 11. 8. 23:13

클로저 Closure

클로저를 잘 이해해야 스위프트의 함수형 프로그래밍 패러다임 스타일을 좀 더 명확하게 이해할 수 있다. 스위프트의 클로저는 다른 프로그래밍 언어의 람다와 유사하다. 클로저는 일정 기능을 하는 코드를 하나의 블록으로 모아놓은 것을 말한다.

클로저는 변수나 상수가 선언된 위치에서 참조를 획득하고 저장할 수 있다. 이를 변수나 상수의 클로징이라고 하며 여기서 클로저가 착안되었다.

클로저의 몇 가지 모양 중 하나가 함수이다.

클로저는 세가지 형태가 있다.

  • 이름이 있으면서 어떤 값도 획득하지 않는 전역함수의 형태
  • 이름이 있으면서 다른 함수 내부의 값을 획득할 수 있는 중첩된 함수의 형태
  • 이름이 없고 주변 문맥에 따라 값을 획득할 수 있는 축약 문법으로 작성한 형태

클로저의 다양한 표현방법

  • 클로저는 매개변수와 반환 값의 타입을 문맥을 통해 유추할 수 있기 때문에 매개변수와 반환 값의 타입을 생략할 수 있다.
  • 클로저에 단 한 줄의 표현만 들어있다면 암시적으로 이를 반환 값으로 취급한다.
  • 축약된 전달인자 이름을 사용할 수 있다.
  • 후행 클로저 문법을 사용할 수 있다.

클로저 표현 방법은 함수의 모습이 아닌 하나의 블록의 모습으로 표현될 수 있는 방법이다. 클로저 표현 방법은 클로저의 위치를 기준으로 크게 기본 클로저 표현과 후행 클로저 표현이 있다. 또한 각 표현 내에서 가독성을 해치지 않는 선에서 표현을 생략하거나 축약할 수 있는 방법이 있다.

기본 클로저

기본 형식

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

//sorted(by:) 메서드에 클로저 전달
let reversed: [String] = names.sorted (by: { (first: String, second: String) - > Bool in
	return first > second
})

 

후행 클로저

함수나 메서드의 마지막 전달인자로 위치하는 클로저는 함수나 메서드의 소괄호를 다은 후 작성해도 된다. 클로저가 조금 길어지거나 가독성이 떨어질 때 후행 클로저 기능을 사용하면 좋다.

단, 후행 클로저는 맨 마지막 전달인자로 전달되는 클로저에만 해당되므로 전달인자로 클로저 여러개를 전달할 때는 맨 마지막 클로저만 후행 클로저로 사용할 수 있다. 또한 단 하나의 클로저만 전달인자로 전달하는 경우에는 소괄호를 생략할 수 있다.

또한 매개변수에 클로저가 여러 개 있는 경우, 다중 후행 클로저 문법을 사용할 수 있다. 다중 후행 클로저를 사용하는 경우, 중괄호를 열고 닫음으로써 클로저를 표현하며 첫번째 클로저의 전달인자 레이블은 생략한다.

 

// 후행 클로저의 사용
let reversed: [String] = names.sorted() {(first: String, second: String) - > Bool in
	return first > second
}

//sorted(by:) 메서드의 소괄호까지 생략 가능하다.
let reversed: [String] = names.sorted{(first: String, second: String) - > Bool in
	return first > second
}

func doSomething(do: (String) - > Void, onSuccess: (Any) - > Void, onFailure: (Error) -> Void){
	//do something
}

// 다중 후행 클로저의 사용
doSomething{(something: String) in
	//do closure
} onSuccess: {(result: Any) in
	// success closure
} onFailure: {(error: Error) in
	// failure closure
}

 

클로저 표현 간소화

  • 문맥을 이용한 타입 유추
    • 메서드의 전달인자로 전달하는 클로저는 메서드에서 요구하는 형태로 전달한다. 전달인자로 전달할 클로저는 이미 적합한 타입을 준수하고 있다고 유추하여 문맥에 따라 적절히 타입을 유추할 수 있다.
  • 단축인자 이름
    • 단축 인자 이름은 첫 번째 전달인자부터 $0, $1, $2... 순서로 $와 숫자의 조합으로 표현한다. 단축 인자 표현을 사용하면 매개변수 및 반환타입과 실행 코드를 구분하기 위해 사용했던 키워드 in을 사용할 필요도 없어진다.
    // 단축 인자 이름을 사용한 표현
    let reversed: [String] = names.sorted{
    	return $0 > $1 
    }​
  • 암시적 반환 표현
    • return 키워드마저 생략할 수 있다. 만약 클로저가 반환 값을 갖는 클로저이고 실행문이 단 한 줄이라면 실행문을 반환값으로 사용할 수 있다.
    // 암시적 반환 표현의 사용
    let reversed: [String = names.sorted {$0 > $1 }​