반응형

코틀린에서 함수의 파라미터로 람다식을 넘겨줄 경우 인텔리J 또는 안드로이드 스튜디오는 다음과 같은 Warning을 표시한다.

"lambda arguments should be moved out of parentheses"

람다를 괄호 밖으로 빼라는 말이다.
예를 들어 아래와 같은 경우에 위와 같은 경고가 떴었다.

view.next_button.setOnClickListener({
    if(!isPasswordValid(password_edit_text.text!!)) {
        password_text_input.error = getString(R.string.shr_error_password)
    } else {
        password_text_input.error = null
        (activity as NavigationHost).navigateTo(ProductGridFragment(), false)
    }
})

위 예는 안드로이드 스튜디오에서 button에 OnClickListener를 설정하기 위해 람다를 넘겨준 예이다.
컴파일에는 문제가 없고, 정상 동작 하기 때문에 그냥 넘어가도 될 일이지만 아주 강력하게 노란색 밑줄을 띄워가면서 IDE가 경고를 하고 있기 때문에 고쳐보도록 하겠다.

코틀린에는 람다(Lambda)를 파라미터로 넘겨주는 방법에는 다음 3가지가 있다.

view.onClick({ toast(it.toString())} ) // 1
view.onClick() { toast(it.toString()) } // 2
view.onClick { toast(it.toString()) } // 3

1번은 함수의 소괄호 안에 파라미터로 람다가 들어가는 경우다.
2번은 함수의 소괄호가 끝나고 곧바로 람다가 이어오는 경우다.
3번은 함수의 소괄호를 생략하고 곧바로 람다가 이어오는 경우다.

1번 방법이 바로 위에서 경고를 발생시켰던 방법이다.
1번에서 발생했던 경고가 "람다를 괄호 밖으로 빼라!" 였으니 2번 혹은 3번으로 하면 왠지 해결 될 것 같다.
한 번 해보자.

 

view.next_button.setOnClickListener() {
    if(!isPasswordValid(password_edit_text.text!!)) {
        password_text_input.error = getString(R.string.shr_error_password)
    } else {
        password_text_input.error = null
        (activity as NavigationHost).navigateTo(ProductGridFragment(), false)
    }
}

2번의 방법으로 변형했다. 확실히 7 라인에 걸쳐있던 노랑색 밑줄 경고가 사라졌다.
하지만 완전히 경고가 사라진 것은 아닌데, 안드로이드 스튜디오(또는 인텔리제이)는 setOnClickListener()에서 소괄호()를 어둡게 처리하고선 경고한다. 쓸모없는 소괄호라고!

1번보다는 많이 좋아졌지만 여전히 찝찝하다. 경고가 완전히 없길 바란다. 그래서 3번으로 바꿔보았다.

view.next_button.setOnClickListener {
    if(!isPasswordValid(password_edit_text.text!!)) {
        password_text_input.error = getString(R.string.shr_error_password)
    } else {
        password_text_input.error = null
        (activity as NavigationHost).navigateTo(ProductGridFragment(), false)
    }
}

3번으로 바꿨더니, 경고가 말끔히 사라졌다. 기분은 좋은데 이쯤 되니 또 의문이 든다.
그렇다면 아예 문법 체계를 3번만 강제하면 될 것이지 왜 3가지 방식이나 열어 놓고서 우리에게 경고를 날리는 것일까?

그래서 코틀린 스타일 가이드(Kotlin Style Guide)를 살펴봤더니 때에 따라서는 3번을 사용하지 못하고 1번, 2번의 방식을 써야하는 순간이 있음을 알게 됐다.

람다를 소괄호에서 빼내서 함수를 콜하는 부분 뒤에 중괄호를 열고 람다를 사용할 수 있는 경우는 그 함수의 파라미터 마지막에 Function이 오는 경우다. 즉 파라미터가 (fun, Int, String) 의 꼴처럼 함수가 파라미터의 마지막이 아닐 경우에는 1번의 방식대로 사용하거나 아니면 별도의 변수에 함수를 저장하여 사용해야 한다.

그리고 이에 근거하여 함수의 파라미터가 단 하나의 람다만을 가질 경우에는 소괄호를 생략하고 3번의 방식대로 사용할 수 있고, 람다 이외의 파라미터를 필요로 하는 함수는 3번처럼 소괄호를 생략하지 못하고 2번 방식으로 나머지 파라미터를 채운 후에 람다가 이어오게 해야 한다.

 


무슨 말인지 잘 모르겠거나 일일이 신경 쓰기 귀찮은 사람을 위해 IntelliJ나 Android Studio에서 Alt + Enter 누르면 IDE가 알아서 변경해준다...ㅎ(허탈)

반응형
반응형