프로그래밍/Kotlin

[Kotlin] 클로저(Closure)에 대해 알아보자

Lou Park 2023. 3. 20. 00:43

Closure와 일반함수의 차이점

  • Closure는 outer scope에 있는 변수에 접근할 수 있지만, 일반 함수는 그렇지 못하다. 일반 함수는 자신이 정의된 영역 내에서만 변수를 사용할 수 있다.
  • Closure는 함수를 값으로 취급하여 변수에 저장하거나 다른 함수의 인자나 반환값으로 사용할 수 있지만, 일반 함수는 그렇지 못하다. 일반 함수는 이름을 통해서만 호출할 수 있다.
  • Closure는 실행 시점에 생성되고 소멸되지만, 일반 함수는 컴파일 시점에 생성되고 소멸되지 않는다. Closure는 상황에 따라 다른 값을 가질 수 있지만, 일반 함수는 항상 동일한 값을 가진다.

 

Kotlin closure

Kotlin에서 Closure는 상위 함수의 영역에 있는 변수에 접근할 수 있는 함수다. Kotlin은 Closure를 지원하므로 익명함수(Anonymous function)는 함수 밖에서 정의된 변수에 접근할 수 있다. 예로, 다음과 같은 코드가 가능하다.

var sum = 0
ints.filter { it > 0 }.forEach { sum += it }
print(sum)

위의 코드에서 forEach의 인자 익명함수는 밖에 정의된 sum에 값을 저장한다. Closure는 outer scope의 변수를 참조할 수 있으므로 복잡한 구조를 간단히 만들 수 있다.

 

Closure를 만드는 방법은 람다식(Lambda expression)이나 익명함수를 사용하면 된다. 람다식은 중괄호 안에 매개변수와 화살표(->) 그리고 함수 본문을 작성한다. 익명함수는 fun 키워드와 매개변수, 반환타입 그리고 함수 본문을 작성한다. 예를 들어, 다음과 같은 코드가 있다.

val add: (Int, Int) -> Int = { x: Int, y: Int -> x + y }
val multiply = fun(x: Int, y: Int): Int { return x * y }

위의 코드에서 add는 람다식으로 정의된 Closure이고 multiply는 익명함수로 정의된 Closure이다. 두 함수 모두 outer scope에 있는 변수에 접근할 수 있다.

 

Closure의 활용

Closure는 언제 유용하고 어떻게 활용할 수 있을까?

  • 함수를 값으로 취급하여 다른 함수의 인자나 반환값으로 사용하고 싶을 때. Closure는 고차함수(high-order function)와 함께 사용되어 함수형 프로그래밍을 가능하게 한다. 예를 들어, map, filter, reduce 같은 함수는 Closure를 인자로 받아서 컬렉션에 대한 연산을 수행한다.
  • 외부 변수의 값을 변경하거나 보존하고 싶을 때. Closure는 outer scope에 있는 변수에 접근하고 수정할 수 있으므로 상태를 유지할 수 있다. 예를 들어, 카운터나 메모이제이션 등의 기능을 구현할 때 Closure를 사용할 수 있다.
  • 콜백(callback)이나 리스너(listener)와 같은 비동기적인 작업을 처리하고 싶을 때. Closure는 실행 시점에 생성되고 소멸되므로 비동기적인 작업에서도 outer scope에 있는 변수에 접근할 수 있다. 예를 들어, 안드로이드에서 View에 Click Listener를 설정할 때 Closure를 사용할 수 있다.

 

참고자료

https://codechacha.com/ko/kotlin-closures/
https://www.geeksforgeeks.org/closures-in-kotlin/
https://stackoverflow.com/questions/50300199/kotlin-closure-to-solve-logical-and-operation