• 카테고리

    질문 & 답변
  • 세부 분야

    모바일 앱 개발

  • 해결 여부

    미해결

클로저 타입 질문입니다.

20.01.06 18:58 작성 조회수 250

0

강의를 듣다가 궁금한게 생겨서 질문 드립니다.

아래 질문에 답변 해주신것과 다르게 filterStringClosure 함수 선언문에서 closure라는 파라미터는  '클로저 타입'이 아닌, 스트링을 받아 bool을 반환하는 단순 '함수 타입'인걸로 이해를 했습니다. (질문1. 클로저 타입이란게 정의 되어 있는건 가요?)

때문에

func findA(str:String)->Bool{

    if str.first?.description == "A"{

        return true

    }

    else {

              return false

     }

}

와 같이 클로저가 아닌 일반 함수도 매개변수로 들어갈수 있는데 굳이 (질문 2. 타입 정도만 생략된 클로저(클로저를 쓰는 이유는 축약때문에 쓰는 것 같은데 함수와 코드 길이가 비슷할 것 같아서)를 사용하는 이유)와 (질문 3.극한으로 축약되지 않은 클로저와 일반함수 중 현업에선 어떤걸 더 사용하는지 궁금합니다.) (질문 4. 또 클로저를 사용했을때 메모리나 속도 차이가 있는지도 궁금합니다.)

let add: (Int, Int) -> Int = {$0 + $1} 수준의 축약이 아닌 이상 현직 개발자들이 func 대신 closure를 선호하는 이유가 궁금합니다. 그냥 개인 코딩 스타일이라고 봐도 될까요?

답변 1

답변을 작성해보세요.

1

우선 클로저라는건 함수와 같지만 이름만 없는 함수(익명함수)라고 생각하시면 됩니다.

함수라는게 받는 파라미터와 리턴값으로 이루어진 구조 입니다.

구조를 그대로 사용하는걸 클로저 라고 생각하시면 됩니다.

넓은 의미로 swift에서는 함수와 클로저는 같다고 봐도 크게 무리는 없습니다.

그리고 클로저를 쓰면 좋은 이유가 몇가지 있는데 

대표적으로

축약으로 인한 코드 가독성을 높이는 것입니다.

정렬하는 코드를 축약 단계별로 보면 아래와 같습니다

1.

names.sorted(by: { (s1: String, s2: String) -> Bool in

    return s1 < s2

})

2.

names.sorted(by: { s1, s2 in return s1 < s2 } )

3.

names.sorted(by: { s1, s2 in s1 < s2 } )

4.

names.sorted(by: { $0 < $1 } )

5.

names.sorted { $0 < $1 }

6.

names.sorted(by: <)

보시면 전혀 축약하지 않는것과 최대로 축약한 문법의 줄어드는 차이가 엄청나죠?

이런 코드들이 모이면 당연히 가독성 또한 엄청난 차이가 생깁니다.

실무에서는 최대로 축약한 쪽으로 사용하는게 일반적입니다.

물론 축약을 거의 안하는 개발자분들도 많이 있겠죠

그런건 개발자의 취향? 정도로 생각해도 크게 무리 없을 같습니다.

특정 상황에 따라 축약 안하는 쪽이 보기 좋을수는 있을 것 같습니다.

그리고 클로저의 하나의 장점은 순차적으로 어떻게 처리될지 예측하기 쉬운형태로 코딩을 있다는 것입니다.

우리가 많이 쓰는 present 화면을 띄우는 함수를 보시면 아래구조 처럼 되어 있습니다.

present(_ viewControllerToPresent: UIViewController

    animated flag: Bool

  completion: (() -> Void)? = nil)

실제로 쓸때는 아래와 같은 모습으로 후행클로저에 present 후에 해야할 로직을 추가하면

개발자가 저 로직을 보고 자연스럽게 present하는데 present하고 후에 무언가를 실행한다고 연결되서 읽힙니다.

   self.present(someVC, animated: true) {

            // some logic

      }

 

 

조건이 많은걸 예로 들어볼까요

숫자가 쭉 있는 array가 있습니다.

1. nil을 없앤다.

2. 5이하인 값만 가져온다.

3. 가져온값을 모두 더한다.

이 세가지 조건에 대한 로직을 어떻게 짜야 할까요?

let numbers: [Int?] = [1, 2, nil, 3, 4, 5, nil, 6, 7, 10, 20, 30]

let result: Int = numbers

    .compactMap({ $0 })

    .filter({ $0 <= 5 })

    .reduce(0, +)

자 이렇게 하면 됩니다.

저 문법에 대해 알고 있는 개발자라면 어떻게 순차적으로 처리되는지 바로 이해되겠죠?

이렇게 순차적으로 처리하는 로직을 자연스럽게 읽을 있게 코딩할 수 있는 것 또한 클로저의 장점이라 생각하시면 같습니다.

밖에 클로저를 쓰면 좋은점이 몇가지 있는데 크게 이정도라고 생각하시면 나중에 자연스럽게 추가적인 장점은 익히게 될겁니다.

참고로 속도에 대한 이슈는 이상하게 로직 짜는거 아니라면 고려할 만큼 차이가 나거나 하지 않습니다.

그러니 속도 때문에 쓰고 안쓰고 결정하기에는 너무 미미한 변수라고 생각하시면 될 것 같습니다.

도움이 되시길 바라며 즐거운 개발하시기 바랍니다~