[Swift] Closure : 함수 안에 함수

2020. 4. 11. 20:17컴퓨터언어/Swift

728x90
반응형

Closure는 함수의 정의부와 실행부를 합쳐줌으로써 코드를 매우 간결하고 깔쌈하게 만들어준다.

 

일반적으로 함수를 사용할 때는,

함수를 정의하는 부분과(아래)

func addOne(inputNum: Int) -> Int {
	return inputNum + 1
}

호출하여 실행하는 부분이(아래)

addOne(10)

위와 같이 따로 놀게 마련이다.

 

하지만 Closure는 불필요한 코딩을 줄여주고 보기에도 더 Swifty, Sexy하다.

 

배열 내 원소에 각각 1씩 더해주는 예제를 통해 더 알아보도록 하자.

 

아래 배열 array에는 Integer 원소 1부터 6까지 들어있다.

var array = [1, 2, 3, 4, 5, 6]

 

원소 각각을 호출하여 addOne을 실행하기 위해 우리는 map() 함수를 이용할 수 있다.

답을 구하기 위해서는 array에 map함수를 걸어주고, 그 인자로 우리가 만든 addOne 함수를 다시 넣어주면 끝난다.

var array = [1, 2, 3, 4, 5, 6]

func addOne(inputNum: Int) -> Int {
	return inputNum + 1
}

array.map(addOne)

하지만 Sexy한 Code를 위해 Closure로 가보겠다.

 

1. 먼저 func 키워드와 함수 이름을 지운다.

(inputNum: Int) -> Int {
	return inputNum + 1
}

2. 그 다음, 함수 전체를 중괄호{}로 감싸도록 여는 중괄호 위치를 바꿔준다.

{(inputNum: Int) -> Int
	return inputNum + 1
}

3. 함수반환 데이터타입인 -> Int 뒤에 in 을 써준다.

{(inputNum: Int) -> Int in
	return inputNum + 1
}

 

4. 3번의 결과를 array.map()의 괄호 안에 그대로 넣어주면 끝난다.

var array = [1, 2, 3, 4, 5, 6]

array.map({(inputNum: Int) -> Int in
	return inputNum + 1
})

하지만 더 Sexy Swifty Freaky하게 가보자.

 

1. Swift는 타입추론이 가능하기 때문에, Closure 내부에서는 데이터 타입을 생략할 수 있다.

즉, 우리는 현재 array를 갖고 놀고 있는 중이기 때문에, array 내부의 각각의 원소들이 각각 map으로 들어오면서 자동으로 Integer임이 확연하기 때문이다.

따라서 입력형과 반환형 모두 Int가 생략 가능하다.

var array = [1, 2, 3, 4, 5, 6]

array.map({(inputNum) in
	return inputNum + 1
})

2. 더 나아가보자.

return 마저 생략 가능하다.

var array = [1, 2, 3, 4, 5, 6]

array.map({ (inputNum) in inputNum + 1 })

3. 더 나아가보자.

위 식은 입력되는 (inputNum)이 반환될 때 inputNum + 1이 됨을 의미한다.

즉 inputNum을 요리하고 있음이 명확하다.

따라서 입력부분을 완전히 생략한 후,

반환부분을 parameter의 순서에 따라 $0, $1, $2, ... 로 대체 가능하다!

var array = [1, 2, 3, 4, 5, 6]

array.map({ $0 + 1 })

4. 더 나아가보자.

Closure로 설정완료된 함수는 () 밖으로 독립적으로 뺄 수 있다. 여기서는 인수가 addOne 하나뿐이었으므로 아래와 같이 생략 가능하다.

var array = [1, 2, 3, 4, 5, 6]

array.map { $0 + 1 }

결과적으로 우리는 식을 완전 간단화하게 되었다.

var array = [1, 2, 3, 4, 5, 6]

func addOne(inputNum: Int) -> Int {
	return inputNum + 1
}

array.map(addOne)

var array = [1, 2, 3, 4, 5, 6]

array.map { $0 + 1 }

 

이처럼 Closure를 통한 심플한 표현은 더 복잡한 로직에서 빛을 발할 것으로 기대된다!

 

참고)

위와 같은 Int 원소를 String으로 바꾸려면, String Interpolation 방식을 이용하면 간단히 끝난다.

var array = [1, 2, 3, 4, 5, 6]

array.map { "\($0 + 1)" }
728x90
반응형