클로저는 내부함수가 외부함수의 context에 접근 할 수 있는 것을 가리킨다.

내부함수에서 외부함수의 데이터를 사용할 경우 외부함수의 코드블럭이 끝나도 내부함수에서 참조한 변수가 계속 살아있게된다. 이 뜻을 의미하려면 다음 코드예시를 보자.

fun main() {
    fun outer(): () -> Int{
        var x = 10
        var innerFunc = fun():Int{
            return println(++x)
        }
        return innerFunc
    }

    val func1 = outer()
    
    func1() // 결과: 11
    func1() // 무슨값이 나올지 한번 맞춰보세요!
}

정답은 외부함수 x 값이 살아있어 12가 나오게 된다.

이처럼 기본적인 개념은 어렵지 않다. 하지만 실제로는 어떻게 사용할까?

		fun updateCommentCount(commentCount: CommentCount) {
        update(commentCount.postId) {
            it.commentCount = commentCount.commentCount
        }
    }

    private fun update(id: Long, action: (Content) -> Unit) {
        for ((i, content) in snapshot().withIndex()) {
            content?.let {
                if (it.id == id) {
                    action(it)
                    this@CommunityAdapter.notifyItemChanged(i)
                    return
                }
            }
        }
    }

위의 예시 함수를 보자.

update라는 함수가 정의되어있다.
id를 파라미터로 받고있는것을 알 수 있다.
그리고 뒤에 action을 실행시키는데 Content를 받아 Unit을 반환한다.

익숙한 for문을 돌고 withIndex를 이용하여 index와 content를 반환해준다.

content : Content 이기 때문에 content.let을 통해서 action에 넣을 Content Type을 준비한다.

content.id(==it.id) 가 파라미터로 받은 id와 동일한지 비교하고 맞다면

action(it)을 실행시킨다. 이때의 it은 파라미터부분에 정의한 Content Type 이다.

그 위의 updateCommentCount메서드를 보자.

원하는 파라미터를 받고 update 메서드를 호출하면서 id를 파라미터로 넣어준다.

이때 람다식에 나타나는 it은 action(Content)의 Content임을 알 수 있다.

그리고 람다식을 실행 시킬 수 있다.


profile
러닝커브를 따라서 등반중입니다.

0개의 댓글