클로져를 이해할 때 따라 쳐 보면 좋은 예제 코드




어쩌다 보니 클로져를 공부하면서 정리하는 글이 점점 많아집니다. 그만큼 중요하고, 또 많이 사용하고 있기 때문이겠죠. 오늘은 클로져를 이해하면서 사용했던 샘플 코드를 정리해보았습니다.

함수 vs 클로져

함수를 정의하고, 그 함수를 호출하는 것은 많은 분들이 익숙할 것이라고 생각합니다. 보통 다음과 같은 코드를 보면 이해할 수 있죠.

func sayHi() {
    print("Hi")
}

sayHi() // Hi

클로져는 이름 없는 함수라고 하죠? 이름이 없는 함수를 만들고 이름을 붙여서 호출 해 보겠습니다.

let sayHiClosure = {
    print("Hi")
}

sayHiClosure() // Hi

그러니까 잘 살펴보면 클로져 앞에 이름을 붙이고 func 키워드 까지 붙이면 함수랑 똑같이 생겨지는 군요!

매개변수, 반환타입

여기서 부터 헷갈리기 시작합니다. 위의 예제는 아무값도 입력받지 않고 반환하지 않는 아주 단순한 형태입니다. 그렇다면 숫자를 2개 입력받아서 합을 구하는 함수와 클로져를 만들고 비교해볼까요?

func sum(_ a: Int, _ b: Int) -> Int {
    return a + b
}
print(sum(3,6)) // 9

let sumClosure: (Int, Int) -> Int = { a, b in
        return a + b
}
print(sumClosure(2, 5)) // 7

결국 우리가 하고 있는 행위는 이름없는 클로져에 이름을 붙이고 있는 것 입니다. 그러면 이쯤에서 왜 클로져를 쓰는가에 대해서 생각해 보아야 합니다.

언제 함수? 언제 클로져?

위 예제에서 두 숫자를 더해서 합을 반환하는 함수를 위에서 만들어 보았습니다. 그렇다면 뺼샘과, 나눗셈과, 곱셈은 어떨까요? 우리의 함수를 쓸지 안쓸지도 모르는데 구현해 놓는다면 너무나 힘들 것 입니다. 그냥 (Int, Int) -> Int 라고 타입을 지정한 다음에 알아서 구현해서 쓰세요 하면, 사용자는 자신이 필요한 내용을 구현해서 쓸 수 있습니다. 코드로 예제를 살펴보시죠!

연산자 만큼 함수를 구현해야 합니다.

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

func sub(_ a: Int, _ b: Int) -> Int {
    return a - b
}

func devide(_ a: Int, _ b: Int) -> Int {
    guard b != 0 else { return 0 }
    return a / b
}

func multiply(_ a: Int, _ b: Int) -> Int {
    return a * b
}

클로져를 이용해서 만들면 이렇게 만들어 볼 수 있겠네요.

func operate(_ a: Int, _ b: Int, operation: (Int, Int) -> Int) -> Int {
    return operation(a,b)
}
operate(3, 4) { a, b in
    return a * b
}

이렇게 정의 해 놓으면 코드가 좀 더 확장성 있어집니다. 물론 확장성 있는 코드가 더 좋은 코드라는 의미는 아닙니다.

매개변수로 입력 받은 클로져

항상 결국에 우리는 이 글을 completeHandlerhandler 같은 녀석들이 이해가 가지 않아서 읽고 있을 것 입니다. 위 내용을 정리해보면, completeHandler는 클로져이고(이름이 없는 함수) 이 클로저에 내가 하고 싶은 것을 담아서 보내거나 받아서 처리하는 녀셕 입니다.

아마 구현인 이런식으로 되어 있을 것 입니다.

func doSomething(completeHander: () -> ()) {
    // do tasks

    // do tasks

    // do tasks

    completeHander()
}

doSomething {
    print("done")
}

어떤 일을 하는 함수가 있을 떄, 이 함수에서 해야 할 일을 전부 다 하고 마지막에 completeHander()를 호출 합니다. 그러면 이 함수를 사용하는 사람은 함수에서 하는 일이 다 끝나고나서 하고 싶은 일을 실행할 수 있는것이죠! (끼워넣기!)

정리

클로져를 설명하면서 자주 사용했던 코드들을 정리하면서 공유드렸습니다. 혹시나 더 궁금한 부분들이 있다면 질문 남겨주시기 바랍니다.

댓글

이 블로그의 인기 게시물

[IOS] AppDelegate는 뭐하는 녀석이지?

[git] git의 upstream과 origin 헷갈리는 사람 손!

[git] Github 이슈 라벨(issue labels)