맛동산이

스위프트 스터디 6탄) 클로저 (Closures) 본문

앱/Swift 문법

스위프트 스터디 6탄) 클로저 (Closures)

진ddang 2023. 7. 8. 16:15

 

스위프트 공식문서를 참조하였습니다.



함수를 클로저 표현으로 만드는 방법

  1. func 키워드와 함수명을 지운다.
  1. 뒤의 { 를 앞으로 가져오고 그위치에 in을 쓴다.
func clouser(n1 : Int, n2: Int)->Int{ 	return n1+n2 } //이거를 클로저로 바꾸면 //1. func과 함수명 지우기  (n1: Int, n2: Int)->Int{ 	return n1+n2 }  //2 in쓰기  {(n1: Int, n2: Int)->Int in return n1+n2}  //완성!

 

클로저 표현

정렬 메소드

swift표준 라이브러리 에서는 sorted(by: ) 이라는 정렬 메소드를 제공하고 있다.여기에서 by 뒤에 붙어서 어떠한 방식으로 정렬할 것인지를 정의하는것을 클로저 라고 한다.

let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"] func backward(_ s1: String, _ s2: String) -> Bool {     return s1 > s2 } var reversedNames = names.sorted(by: backward) // reversedNames is equal to ["Ewa", "Daniella", "Chris", "Barry", "Alex"]

이러한 방식으로 함수를 통해 클로저를 만들고, 사용할수 있다.

 

클로저 표현 문법

{ (parameters) -> return type in     statements }

클로저 문법은 다음과 같은 모양을 띄고 있다

단순한 예제를 사용해보면

var reversedNames = names.sorted(by: { (s1: String, s2: String) -> Bool in     return s1 > s2 })

이렇게 사용 할수 있다.

혹은 문맥에서 타입을 추론 하도록 string을 작성해주지 않아도 괜찮다.

또한 반환 키워드를 생략을 할수가 있는데

var reversedNames = names.sorted(by: { s1, s2 in s1 > s2 } )

이러한 형태또한 가능하다. 위의 형태가 타입추론, 그리고 리턴 생략 을 한 형태

최종적으로는 인자 이름또한 축약을 할수가 있는데

이때 $0,$1,$2,$3 이렇게 받는 파라미터의 순서를 통해서 statement를 작성하면 된다.

따라서

var reversedNames = names.sorted(by: { $0 > $1 } )

이렇게 간략하게 표현이 가능하다.

최종적으로 연산자 메소드를 사용해서 또 축약이 가능하다.

var reversedNames = names.sorted(by: >)

 

후위클로저

func someFunctionThatTakesAClosure(closure: () -> Void) {     // function body goes here }

이러한 형태의 클로져가 있다면, 결국은

아까 했던 정렬 예제를 사용해본다면

var reversedNames = names.sorted(){$0>$1}

이렇게 줄일수 잇는데,

이거를 후위 클로져기 때문에 ()를 생략하고

var reversedNames =names.sorted{$0>$1}

로 작성할수 있다.

map의 예제를 보게 된다면 이렇게 사용가능.

let strings = numbers.map { (number) -> String in     var number = number     var output = ""     repeat {         output = digitNames[number % 10]! + output         number /= 10     } while number > 0     return output } // let strings는 타입 추론에 의해 문자 배열([String])타입을 갖습니다. // 결과는 숫자가 문자로 바뀐 ["OneSix", "FiveEight", "FiveOneZero"]가 됩니다.

 

 

뒤에 갑캡쳐랑, 이스케이핑, 자동클로저가 있지만, 그거는 일단 생략하고

클로저의 반환값은 참조형이라는것만 알아두자.


클로저 예제

func calculater(n1: Int, n2: Int, operater: (Int,Int)->Int)->Int{     return operater(n1, n2) }  func multi(no1: Int, no2: Int)->Int{     return no1 * no2 }  calculater(n1: 2, n2: 3, operater: multi)

원래 이러한 코드가 있다고 했을 때

 

func calculater(n1: Int, n2: Int, operater: (Int,Int)->Int)->Int{     return operater(n1, n2) }  calculater(n1: 2, n2: 3, operater: {(no1: Int, no2: Int)->Int in     return no1 * no2 })

이런식으로 코드를 바꿀수 있다.

 

그리고 위에 말했듯이 첫번째 파라미터와 두번째 파라미터 순서대로 값을 받는것을 통해서 $키워드를 통해 생략해줄수 있다. 따라서 다음과 같이 정리할수 있다.

 

calculater(n1: 2, n2:3, operater: {$0 * $1})  

 

여기에서 한번더 파라미터 이름을 생략할수 있게 된다.

let result = calculater(n1: 2, n2: 3){$0 * $1}

이러한 방법을 후위 클로져 라고한다.

 

또다른 예제

import UIKit  let array = [8,2,7,4,4,2,1]  func addOne(n1: Int)->Int{     return n1 + 1 }  print(array.map(addOne(n1:)))  print(array.map({(n1: Int)->Int in n1+1}))  print(array.map(){$0+1})  print(array.map{$0+1})

이러한 순서로 클로저를 통해 코드를 간략화 할 수 있다.

 

 

클로저에 대해서

let closure: (String)-> String{ 	(name: String)-> String in return "개발하는 \(name)" }

가 클로저의 기본 형태이다.

이를 출력해보면

closure(name: jinyong) // 개발하는 jinyong

 

  • 즉 클로저 그 자체는 그냥 함수라고 생각하면 된다.
  • 하지만 클로저의 중요한 점은 클로저 그자체를 매개변수로 받아올수 있다는 점이다.

 

매개변수로서의 클로저

 


Uploaded by

N2T
반응형