본문 바로가기
프로그래밍/Swift

Swift 클로저, 다시 한번 정리

by Mr-후 2020. 11. 12.
반응형

클로저를 얼마나 다양하게 표현할 수 있는지 보자

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

스위프트의 클로저는 C언어나 Objective-C의 브록(block) 또는 다른 프로그래밍 언어의 람다(lambda)와 유사, 클로저는 일정 기능을 하는 코드를 하나의 블록으로 모아놓은 것을 말하며 함수와 비슷하며 함수 역시 클로저의 한 형태. 

 

클로저의 세 가지 형태.

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

 

예]

스위프트 라이브러리의 sorted(by:) 메서드 정의 

public func sorted(by areInIncreasingOrder: (Element, Element) -> Bool) -> [Element]

 

 

//정렬에 사용될 이름 
let names : [String] = ["wizplan", "eric", "yagom", "jenny"]

 

 

//정렬을 위한 함수 전달 

func backwards(first: String, second: String) -> Bool {
	print("\(first) \(second) 비교중")
    return first > second
}

let reversed: [String] = names.sorted(by: backwords)
print(reversed) 

//["yagom", "wizplan", "jenny", "eric"] 

 

위의 코드들을 클로저 표현을 사용해 좀 더 간결하게 표현. 

클로저 표현은 통상 아래 형식을 따른다. 

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

클로저는 매개변수 기본 값을 사용할 수 없으며 입출력 매개변수를 사용하고 매개변수 이름을 지정한다면 가변 매개변수 또한 사용 가능. 

 

//backword(first:second:) 함수 대신에 sorted(by:) 메서드의 전달인자로 클로저를 직접 전달 

let reversed: [String] = names.sorted(by: { (first:String, secode:String) -> Bool in 
	return first > second
}

 

위의 func backwards(first:second)와 아래 sorted(by:)로 전달되는 인자는 동일하다. 이럴 경우 func backwards가 어디에 구현되어 있는지 찾아다니지 않아도 되므로 편하지만 여러번 동일하게 중복되는 기능일 경우 함수로 구현해 두는 것도 한 방법이다. 

 

후행 클로저

함수나 메서드의 마지막 전달인자로 위치하는 클로저는 함수나 메서드의 소괄호를 닫은 후 작성 가능, 클로저가 길어지거나 가독성이 떨어진다 싶을 때 후행 클로저 기능을 사용하면 좋다. 하지만 후행 클로저는 맨 마지막 전달인자로 전달되는 클로저에만 해당 되므로 전달 인자로 클로저 여러 개를 전달 할 때는 맨 마지막 클로저만 후행 클로저로 사용 가능.

sorted(by:)메서드처럼 단 하나의 클로저만 전달인자로 전달하는 경우에는 소괄호를 생략 가능. 

후행 클로저 표현

//후행 클로저의 사용 
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
}


//암시적 생략을 위해서 다음과 같이도 된다. ㅎㅎ
let reversed: [String] = names.sorted {$0 > $1} 

//위의 예는 클로저 표현 간소화의 극강을 보여주는 예

 

클로저 문법의 in 은 매개변수 및 반환 타입과 실행 코들르 구분하기 위해 사용한다. 간결할하게 표현할 때는 in도 생략 가능하다. 

 

<연산자의 정의>

public func > <T : Comparable>(lhs: T, rhs: T) -> Bool

 

함수 > 자체가 함수의 이름인데 (자바스크립트 jQuery의 $ 같은 식?) 이 함수는 전달인자로 보내기에 충분한 조건을 갖고 있다. 

//연산자 함수를 클로저의 역할로 사용 
let reversed: [String] = names.sorted(by: >) 

 

값 획득. 

반환 타입 () -> Int는 함수객체를 반환한다는 의미. 반환하는 함수는 매개변수를 받지 않고 반환 타입은 Int인 함수로, 호출할 때마다 Int 타입의 값을 반환해준다. 

 값 획득 부분은 읽어보면 대략적으로는 이해가 가는데 정확하지않아 따로 정리하지 않음. 단 변수나 인자의 값의 범위가 소괄호를 내에서 유효한 점에 비추어 보자면 클로저를 포함하는 함수안의 변수나 인자의 값을 참조해서 가지고 있을 수 있는 클로저의 로직을 수행할 수 있다는 점에 대해서는 이해를 하였다. 

 

 

 

반응형

'프로그래밍 > Swift' 카테고리의 다른 글

UILabel Size Animation With layer.anchorPoint  (0) 2021.07.05
@escaping  (0) 2020.11.12
@objc  (0) 2020.11.12
Swift의 where절  (0) 2020.11.12
Swift ForEach 사용 예  (0) 2020.11.12