본문 바로가기
Swift

Swift Closure (일급객체 함수)

by HaningYa 2021. 3. 25.
728x90

Function Type

  • 1st class citizen
    • 함수는 1등 시민
    • 함수는 어디든 갈 수 있다.
    • 함수는 다른 함수의 매개변수가 될 수 있다.
    • 함수가 함수를 리턴할 수 있다.
    • 함수를 변수에 할당할 수 있다.
    • 함수 타입
      • () -> Void 
      • (Int, Int) -> Int

Example 1) 변수에 함수를 할당할 수 있다.

/// Apple example code

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

func multiplyTwoInts(a: Int, b: Int) -> Int
	{ return a * b }
    
var mathFunction:(Int, Int) -> Int = addTwoInts
		//이 자리는 type 자리인데 함수가 들어갈 수 있음
mathFunction(2,3) //5
mathFunction = multiplyTwoInts
mathFunction(2,3) // 6

Example 2) 정보와 일을 둘다 파라미터로 넘길 수 있다.

func addVAT(source: Double) -> Double 
{ return source * 1.1 }

func couponDiscount(source: Double) -> Double 
{ return source * 0.9 }

func finalPrice(source: Double, additional: (Double) -> Double) -> Double {
	let price = additional(source)
    return price
}

let transaction1 = finalPrice(source: 38.5, additional: addVAT)

Example3) Currying: 인자 10개 있는 함수의 경우 10개 인자를 다 기다리지 말고 들어올때 마다 처리할 수 있는 등등
(근데 인차 10개있는 함수는 나쁜거같은데)

func makeAdder(x:Int) -> (Int) -> Int { //매개변수에는 ()를 쳐야함
	func adder(a:Int) -> Int {
    	return x + a
    }
    return adder
}

let add5 = makeAdder(x: 5)	//7
let add10 = makeAdder(x: 10)//12

makeAdder(x:5)(2)			//7

[관련 레퍼런스]

 

[Swift] 커링(Currying)이란?

함수형 프로그래밍을 하다보면 커링(Currying)이라는 말을 종종 들어보셨을 겁니다. 이번 포스트에서는 이 커링에 대해 알아 보겠습니다. 포스트가 제법 깁니다. 😅

jusung.github.io

 

 

Closure

  • A block of code that be stored as variable or passed as parameter

closure: self-contained blocks of functionality / 기능을 내포하고 있는 블럭
함수 => 이름을 가진 클로져(차이점이 있을껀데)

  • 점점 더 많이 사용하고 있는 문법(익숙해져야함)
  • clean, reusable, high-performance code 작성 가능
let sumClosure = { (numbers: [Int]) -> Int in 
	//code that adds together the numbers array
	return total
}

스위프트는 타입을 가져야 하기 때문에 클로져도 타입이 있다.

매개변수의 유무와 리턴타입의 유무에 따라 4가지 타입으로 클로져는 나눠진다.

  • parameter O return O
  • O X
  • X O
  • X X

클로져를 인자로 받는 경우 예시)

음악 플레이리스트를 구성하는데 음악에는 track number, track name, rating 이 있다.

기준에 따라 정렬할 때 sorted(by:) 기본 함수를 사용해 보자 (클로져를 인자로 받는 내장 함수임)

 

let sortedTrack = tracks.sorted{ (firstTrack, secondTrack) -> Bool in
	return firstTrack.trackNumber < secondTrack.trackNumber
}

 

Closure Syntatic suger

1) 리턴 타입을 생략할 경우

let sortedTrack = tracks.sorted{ (firstTrack, secondTrack) in
	return firstTrack.trackNumber < secondTrack.trackNumber
}

2) 매개변수 생략할 경우(위치로 참조)

let sortedTrack = tracks.sorted{
	return $0.trackNumber < $1.trackNumber
}

3) 리턴도 생략할 경우

let sortedTrack = tracks.sorted{ $0.trackNumber < $1.trackNumber }

4) 극한의 생략

let sortedTrack = tracks.sorted(by: <)

Trailing Closure Syntax 

끝에오는 매개변수의 경우에는 따로떼서 매개변수 이름을 날려버리고 클로져로 넘길 수 있다.

func performRequest(url: String, response: (code:Int) -> Void) {}

//의 경우 마지막 매개변수인 reponse를 클로져로 넘길 수 있다.
performRequest(url: "https://www.apple.com"){ (data) in 
	print(data)
}

Collection 함수들

이전 포스팅 참조

 

Swift High Order Function Summary

고차함수란 함수를 다루는 함수 하나 이상의 함수를 인자로 받는다. 함수를 결과로 반환한다. Swift 고차함수 종류 Map Filter Reduce CompactMap FlatMap Map 배열 내부의 값을 하나씩 mapping 하는 역할 각 요.

haningya.tistory.com

Closures capture their environment

중괄호를 써서 블럭을 만들면 블럭 내부에서만 따로 선언을 하고 내부, 외부 scope는 달라지게 된다.

//외부 scope
animate {
	self.view.backgroundColor = .red
    //내부 scope
}
//self를 통해 view를 reference 하고있음
var adder = 5
let myAdder = { [adder] in //capture list
	print(adder + 10)
}

myAdder() //15
adder = 10
myAdder() //15 (capture 한 5가 더해진다)

클로져는 별도의 Queue에서 실행된다.

언제 실행될지, 실행순서가 보장이 되지 않는다.

나중에 실행될때 사용될 값을 capture 하는 것

728x90

'Swift' 카테고리의 다른 글

Swift where syntax  (0) 2020.10.27
Swift High Order Function Summary  (0) 2020.10.06
[DI] Initializer로 Swift 의존성 주입하기  (0) 2020.09.03
ARC - Automatic Reference Counting  (0) 2020.08.24
Swift: 프로퍼티와 메서드  (0) 2020.07.13

댓글