본문 바로가기

iOS/Swift

Swift) 클로저(Closure) 정복하기(1/3) - 클로저, 누구냐 넌

 

 

 

안녕하세요 :) 소들입니다

으휴 저번 주도 쓸데없이 바빴어서 포스팅을 못했네용

나태한 저번주의 나를 반성하며.. 하암..🥱

 

음 전에 제가 Swift의 꽃이 Optional이라고 말한 적 있는데,

Optional 만큼 중요한 Closure라는 개념에 대해 배울 거예요!!!!

 

클로저는 프로그래밍할 때 진~~~~~~~~짜 많이 쓰이니까

꼮꼮 한 번 배울 때 제대로 알아놔둡시다 :)

 

아맞다ㅏ,, Swift 함수에 대해 모르시면 이해하기 힘들어서...

함수부터 정복하고 오시길..

모든 포스팅은 편의 말투로 합니다~!!

 

 

 

 

1. 클로저란?

 

음, 먼저 클로저란 개념에 대해 다시 짚고 가겠음!

다시라고 한 이유는 함수 포스팅에서 잠깐 다뤘었기 때문에,,

 클로저에 관한 내용만 발췌 좀 해왔음..ㅎ 내 포스팅인데 뭐..ㅎ

 

 

클로저라고 하면 보통 익명함수를 뜻한다고 생각할텐데,

사실 func 키워드를 이용해 이름을 붙여주는 함수들도 모두 클로저임!!

 

무슨말이냐면,

클로저는 다음과 같이 두 가지 종류가 있음

 

 

Named Closure가 있고, Unnamed Closure가 있는데

우리가 다음과 같이 선언해왔던 이름이 있는 함수

 

 

func doSomething() {
    print("Somaker")
}

 

 

Named Closure임! 근데, 이를 클로저라 부르지 않고,

그냥 함수라고 부르는 것 뿐임! (그치만 클로저란 사실은 변함 없음)

 

그리고, 다음과 같이 이름을 붙이지 않고 사용하는 함수

 

 

let closure = { print("Somaker") }

 

 

익명함수, 즉 Unnamed Closure라고 부르는 것임

근데 보통 Closure라고 하면 Unnamed Closure를 말하긴 함 :)

따라서, 정리하자면

 

클로저는 Named Clousre & Unnamed Closure 둘다 포함하지만,

보통 Unnamed Closure를 말한다!

 

 

발췌 끝 :)

 

자, 근데 여기서 한 가지를 더 붙이자면,

클로저도 익명이긴 하지만 함수이기 때문에,

1급 객체 함수의 특성을 고대로 다 갖고 있음!!!

 

뭐 함수 정복하기 포스팅에서 배운 

변수나 상수에 대입하고... 리턴할수 있고.. 파라미터로 받을 수 있고 그런 것들 :)

때문에 클로저 또한 자료형을 가지고 있음!

이제 클로저 사용법에 대해서 봐보자 👀

 

 

 

 

2. 클로저 표현식

 

이번엔, 클로저의 표현식에 대해 살펴 보겠음!

 

 

 

 

표현식은 이렇게 쓰는데,

익명 함수인 만큼 func이란 키워드를 쓰지 않음!!!!!

그리고 클로저는 다음과 같이 클로저 헤드 클로저 바디로 이루어져 있는데

 

 

 

 

이 둘을 바로 구분지어주는 게 바로 in 이라는 키워드임!!!!

 

근데 이렇게만 보면 뭔말인지 이해 1도 안 되고요??

실제 어떤 식으로 사용하는지를 봐보면서 이해를 해보자 :)

 

 

 

2-1. Parameter와 Return Type이 둘 다 없는 클로저

 

자, 클로저는 뭐다?? 익명이긴 하지만 함수다!

따라서 Swift에서 1급 객체이기 때문에, 다음과 같이 상수에 클로저를 대입할 수 있음

특히 Parameter와 Return Type이 둘 다 없는 경우는 다음과 같이 사용함

 

 

let closure = { () -> () in
    print("Closure")
}

 

 

고러허다 그러면 의구심이 들 거임

함수처럼 Return Type 없으면 생략해도 되는 거 아님?ㅎㅎ 물론 됨 !!

심지어 Return Type이 있어도 생략 가능하고;; 함수에선 안되는 Parameter조차 생략 가능함;;

 

근데 이건 다음 포스팅인 클로저 경량 문법에서 배울 것이니!

지금은 그냥 교과서적인 표현부터 알고 가겠음 :)

 

 

 

2-2. Parameter와 Return Type이 있는 클로저

 

자, 이런 경우엔 다음과 같이 표시함

 

 

let closure = { (name: String-> String in
    return "Hello, \(name)"
}

 

 

함수와 비슷해 보여서 어려울 것 하나 없지만

한 가지 주의해야 할 것이 있음!!

 

함수 때 배운 대로 Parameter의 "name"은 단독으로 쓰였으니,

Argument Label이자, Parameter Name이겠네여?

 

라고 생각할 수 있지만,

 

클로저에선 Argument Label을 사용하지 않음

 

따라서, name은 Argument Label이 아니고, 오직 Parameter Name임!

따라서 좀이따 보겠지만 다음과 같이 클로저를 호출할 땐

 

 

closure("Sodeul")
closure(name: "Sodeul") //error!

 

 

 Argument Label을 사용하지 않음!

사용하면 에러나염

 

 

자, 이것이 클로저의 표현식 다인데...

어려웠다면 다시 차근차근 읽어보시면 됩니다 :)

 

 

 

 

3. 1급 객체로서 클로저

 

이번엔 1급 객체 함수의 특징을 클로저에 대입시켜 보려고 함

어렵진 않은데 처음 보면 좀 헷갈릴 순 있기에 다뤄봄

 

 

 ⓛ 클로저를 변수나 상수에 대입할 수 있다 

 

음 이건 위에서 봤듯이 

클로저 또한 변수나 상수에 대입할 수 있고

이 대입된 변수나 상수로 실행도 할 수도 있음

 

 

let closure = { () -> () in
    print("Closure")
}

 

 

이런 식으로 대입과 동시에 클로저를 작성할 수도 있고,

또는, 기존에 클로저를 대입한 변수나 상수를

 

 

let closure2 = closure

 

 

이렇게 새로운 변수나 상수에 대입할 수도 있음~_~

 

 

 ② 함수의 파라미터 타입으로 클로저를 전달할 수 있다 

 

 

func doSomething(closure: () -> ()) {
    closure()
}
 

 

 

자, 이런 식으로 함수를 파라미터로 전달받는 doSomething이라는 함수가 있음

이 경우, 파라미터로 함수를 넘겨줘도 되지만

 

 

doSomething(closure: { () -> () in
    print("Hello!")
})
 

 

 

이렇게 클로저를 넘겨줘도 됨!!

이렇게 보니까 헷갈릴 수 있는데 함수 호출을 다음과 같이 생각하면 됨

 

 

 

 

초록색 영역이 클로저로 작성된 부분이고,

이것이 closure란 Argument Label의 Parameter로 전달된 것임!!!

 

그러면 doSomething이란 함수에서 파라미터로 전달받은 함수를 실행하면,

 

 

 

 

우리가 작성한 클로저가 실행 됨:)

 

 

 ③ 함수의 반환 타입으로 클로저를 사용할 수 있다 

 

이또한, 선언부는 기존 함수와 똑같지만,

 

 

func doSomething() -> () -> () {
}
 

 

 

이렇게!!! 

그러나 실제 값을 return할 때 함수가 아닌

 

 

func doSomething() -> () -> () {
    
    return { () -> () in
        print("Hello Sodeul!")
    }
}
 

 

 

이렇게 클로저를 리턴할 수 있음!!!

(문법이 어렵게 느껴질 수 있지만, 다음 포스팅에서 매우 간단해지니 겁먹지 말자..!)

 

또한 호출하는 곳에서 클로저를 받아서 다음과 같이

 

 

let closure = doSomething()
closure()

 

 

실행시킬 수 있음 :)

 

 

 

 

쨔쟌 :-)

 

 

 

 

4. 클로저 실행하기

 

클로저를 실행할 수 있는 방법은 크게 두 가지가 있는데,

 

 

 

4-1. 클로저가 대입된 변수나 상수로 호출하기

 

 

let closure = { () -> String in
    return "Hello Sodeul!"
}

closure()

 

 

이런 식으로 클로저가 대입된 상수 closure를

호출 구문인 ()를 이용해서 실행시킬 수 있음

 

 

 

4-2. 클로저를 직접 실행하기

 

클로저를 변수나 상수에 대입하지 않고 실행시키고 싶다면, (완벽한 일회성)

그땐 클로저를 ( ) 소괄호로 감싸고, 마지막에 호출 구문인 ()를 추가해주면 됨!

 

 

({ () -> () in
    print("Hello Sodeul!")
})()

 

 

 

이렇게!! 그럼 클로저가 

 

 

 

 

호출 된답니댜 :)

 

 

 

 

 

.

.

.

 

이번 포스팅에선 클로저의 정말 기초에 대해 다뤄봤어요!!!

어렵지 않을 것이라 생각 👀

 

근데 저렇게 클로저 사용법이 너무 길고 헷갈리고 하지 않나요...?

많이 사용한다고 했는데 매번 저렇게 쓰면... 쓸 때마다 을매나 귀찮겠어요./....

 

따라서 Swift는 클로저 경량 문법이라는 것을 지원하는데

(클로저를 엄청 단순하고 쉽게 사용할 수 있도록)

이것에 대해선 다음 포스팅에서 다룰게요!!!!

 

저는 기초를 매우 중시하는 자라,

경량 문법만 알아도 되지만, 실제 클로저는 어떻게 생겼는지에 대해서 알아보는 포스팅을 해봤어요 :)

다음 포스팅에서 클로저란 녀석을 더 쉽게 사용해 봅시다!!!

 

그럼 20,000



Calendar
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
최근 댓글
Visits
Today
Yesterday