반응형
LinkedIn 개발자로 성장하면서 남긴 발자취들을 확인하실 수 있습니다.
Github WWDC Student Challenge 및 Cherish, Tiramisul 등 개발한 앱들의 코드를 확인하실 수 있습니다.
개인 앱 : Cherish 내 마음을 들여다보는 시간, 체리시는 디자이너와 PM과 함께 진행 중인 1인 개발 프로젝트입니다.
10년 후, 20년 후 나는 어떤 스토리 텔러가 되어 있을지 궁금하다. 내가 만약에 아직 조금 더 탐구하고 싶은 게 있고, 궁금한 게 있다면, 그게 설사 지금 당장의 내 인생에 도움이 안 되는 것 같더라도 경험해보자. 그 경험들을 온전히 즐기며 내 것으로 만들고, 내 일에 녹여내고... 그러다보면 그 점들이 모여 나란 사람을 그려내는 선이 될 테니까.

Recent Posts
Recent Comments
Total
관리 메뉴

꿈꾸는리버리

Closure 넌 누구냐 ! [1/3] 본문

오뚝이 개발자/swift

Closure 넌 누구냐 ! [1/3]

rriver2 2022. 5. 11. 15:35
반응형

SwiftUI로 개발을 하면서 swift의 부족을 많이 느꼈기 때문에

NC1 끝나고 MC2 본격 시작 전에 swift의 기본기를 다져야 겠다는 생각을 많이 했다.

그래서 이번 주말에 내가 뭘 놓치고 있었는지에 대해 고민한 끝에 closure 로 시작해서,, 고차함수 그리고 optional을 이번주에 공부하기로 했다..! ( 다음주에는 property 예제들로 computed property나 type property가 어디서 사용되는지를 우선 알아보고자 한다.)

적어놔야지 할 거 같아서 !! ㅋㅅㅋ ....

 

그래서 시작한 Closure 공부 !!!

공부하면서 map, filter 같은 거 쓸 때 $0, $1 요런 친구들을 많이 봤었어서 클로저를 진짜 너무 공부하고 싶었다..!!

만약 나와 같은 needs를 느낀다면 !! 본 포스팅이 도움이 되길 바란다....

 

 

 

이렇게 드래그 되어 있는 부분이 closure가 들어가는 부분이다 !

 

 


 closure의 종류 

 

우선... function도 closure라는 것 ! 알고 있었는가...?

closure의 종류에는 named closure와 unnamed closure가 있고,

그 중에 named closure를 function이라고, unnamed closure를 closure라고 통상적으로 부른다.

 

1) named closure ( function )

func function(A : Int, B : Int) -> Bool {
    return A > B
}

let a = function(A : 2, B : 3)

2) unnamed closure ( closure )

let closure = { (A : Int, B : Int) -> Bool in
    return A > B
}

let b = closure(2,3)

 

 

요론 느낌 ?? 비슷한 듯 다른데 차차 둘의 차이를 알아보기로 하자.

 

내가 느끼기에는 Closure은 매개변수로 사용될 때 그 특징을 좀 더 자세하게 알 수 있게 되는 거 같다.

 


 Closure Expressions 

 

Closure은 아래와 같은 형태로 표현을 한다.

💡 Closure expression Syntax 

{ (parameters) -> return type in 	// --> 여기를 closure head
	statements                      // --> 여기를 closure body
}

 

한 예제를 통해 Closure을 알아보기 위해서 알아보려고 한다.

 

예제 )

Calculate라는 함수가 있는데,

이 함수의 매개 변수에는 두개의 정수와, +, -, *, % 을 계산하는 method Closure인 (Int, Int) -> Int 가 있다.

func Calculate(left : Int, right : Int, method : (Int , Int) -> Int) -> Int {
    return method(left, right)
}

 우선 func ! 

앞서 이야기 한 대로 closure의 종류에는 named closure와 unnamed closure가 있고,

그 중에 named closure를 function이라고, unnamed closure를 closure라고 통상적으로 부른다.

 

method closure의 자리에 unnamed closure가 들어가는 예제를 보기에 앞서

method closure 자리에 named closure 즉, function이 들어가도록 코드를 짜보자.

아래와 같이 addAB라는 함수를 만들어서 안에 넣으면 된다.

func addAB(left : Int , right : Int) -> Int {
    left + right
}
Calculate(left: 1, right: 2, method: addAB)

 unnamed closure

위에 addAB에서 드래그 한 부분을 method의 여기에 넣으면 unnamed closure가 완성이다 !

이때 위에서 알아본 Closure expression Syntax 를 주의해서 closure head와 body를 분리해 적어보자.

{ (parameters) -> return type in 	// --> 여기를 closure head
	statements                      // --> 여기를 closure body
}

결과는 다음과 같다 !

Calculate(left: 1, right: 2, method: { (left : Int , right : Int) -> Int in
    return left + right
})

 

이런식으로 종류에 따라 덧셈, 뺄셈, 곱셈, 나눗셈의 기능을 하는 Calculate 함수, 4개 만들 수 있다.

Calculate(left: 1, right: 2, method: { (left : Int , right : Int) -> Int in
    return left + right
})

Calculate(left: 1, right: 2, method: { (left : Int , right : Int) -> Int in
    return left - right
})

Calculate(left: 1, right: 2, method: { (left : Int , right : Int) -> Int in
    return left * right
})

Calculate(left: 1, right: 2, method: { (left : Int , right : Int) -> Int in
    return left % right
})

근데 해당 내용이 뭘 의미하는지 이해하기도 힘들고 너무 길다고 느껴진다.

 

 

그래서 짜란 ~ Closure를 줄여보자.

아래에 하늘 색 선으로 나타낸 부분이 Closure이다.

Closure을 줄이는 방법이 몇 가지 있는데 다 줄이고 나면, 요로케 코드가 줄어든다 !

훨씬 이해하기 쉬운 형태로 된... 듯 ??

 


 이제 Closure을 줄이는 방법을 알아보자 ! 

Calculate(left: 1, right: 2, method: { (left : Int , right : Int) -> Int in
    return left + right
})

+을 수행하는 Calculate로, 매개변수에 +을 수행하는 closure가 있다.

 

이제 이 3줄 짜리 Calculate 함수의 매개변수 method 클로저를 하나하나 줄여나갈 건데,

윗 코드와 차근차근 비교해가면서 살펴보면 좋을 거 같다 :)

 

 

1) Trailing Closure

💡 Trailing은 항상 오른쪽이 아니라, "마지막 부분" 라고 생각하는 게 맞다고 한다.
한국에서는 왼 -> 오른쪽으로 글씨를 써내려가기 때문에 leading이 왼쪽, trailing이 오른쪽인데, 
다른 국가에서는 반대일 수 있다. 

 

말 그대로 Trailing Closure은 "젤 오른쪽(마지막)" 파라매터가 Closure일 때 쓸 수 있다.

 

" 마지막" 파라매터가 Closure일 때,

Argument Label을 생략하고 파라매터 형식이 아닌 함수 뒤에 붙여 작성 "

 

위 함수에서 마지막 method는 Closure이기 때문에 Trailing Closure로 나타낼 수 있다.

 

다음과 같이 "method" (Argument Label)을 없애고, 뒤에 Closure의 형태로 붙여 쓰면 된다.

Calculate(left: 1, right: 2){ (left : Int , right : Int) -> Int in
    return left + right
}
// 기존
Calculate(left: 1, right: 2, method: { (left : Int , right : Int) -> Int in
    return left + right
})

2) Inferring Type From Context

// Calculate의 정의

func Calculate(left : Int, right : Int, method : (Int , Int) -> Int) -> Int{
	return method(left, right)
}

이 Calculate 함수의 정의에서 method의 형태가 (Int , Int) -> Int인 Closure임을 확인 할 수 있다.

Calculate(left: 1, right: 2){ ( left , right ) in
    return left + right
}

라서 method Closure에 type을 굳이 다 적지 않더라도 문맥상에서 type이 추론이 가능하기 때문에

:Int 이런 type을 나타내는 부분이 생략 가능하다 :)

// 기존
Calculate(left: 1, right: 2, method: { (left : Int , right : Int) -> Int in
    return left + right
})

 

 

3) Implicit Returns from Single-Expression Closures

딸랑 한 줄 있는 함수에서는 return을 굳이 적어주지 않더라도 그 값이 반환 된다는 것을 암묵적으로 알 수 있다.

Calculate(left: 1, right: 2){ ( left , right ) in
    left + right
}
// 기존
Calculate(left: 1, right: 2, method: { (left : Int , right : Int) -> Int in
    return left + right
})

 

4) Shorthand Argument Names

left는 첫번째 파라매터, right는 두번째 파라매터이다.

느껴지겠지만, 파라매터의 이름보다는 몇 번째 위치인지의 값을 넣으면 되는지가 더 중요하다.

따라서 left -> $0 으로,  right -> $1로 표현할 수 있다.

( 하지만 경우에 따라 남겨두는 게 가독성이 더 좋은 경우가 있어서, 상황에 따라 맞게 줄이는 것이 좋다. )

Calculate(left: 1, right: 2){ $0 + $1 }
// 기존
Calculate(left: 1, right: 2, method: { (left : Int , right : Int) -> Int in
    return left + right
})

 


 

이번 포스팅에서는 closure의 기본에 대해서 알아봤다.

다음 포스팅에서는 closure의 capture 개념과 closure가 reference type이라는 것을 주제로 closure와 더 친해지고자 한다.

 

 

 

https://docs.swift.org/swift-book/LanguageGuide/Closures.html#ID97

 

Closures — The Swift Programming Language (Swift 5.6)

Closures Closures are self-contained blocks of functionality that can be passed around and used in your code. Closures in Swift are similar to blocks in C and Objective-C and to lambdas in other programming languages. Closures can capture and store referen

docs.swift.org

 

 

반응형

'오뚝이 개발자 > swift' 카테고리의 다른 글

removeLast() vs popLast()  (0) 2022.05.24
[2/2] optional chaining  (6) 2022.05.14
[1/2] Optional unwrapping  (0) 2022.05.14
Closure에서의 Capture ( feat . reference type) [2/3]  (4) 2022.05.11
Property(1/4) - > StoredProperty  (0) 2022.04.27
Comments