본문 바로가기
Android/Kotlin

Kotlin : run, with, let, also and apply

by 2Plus 2020. 5. 17.

Scoping Function

Kotlin의 scoping function들에 대해 정리해보려고 한다. scoping function은 다음과 같이 6가지 종류가 있다.

 `run`, `with`, `T.run`, `T.let`, `T.also`, `T.apply`

 

Scoping Function - "run"

[예시 코드 1]

 

 

[실행 결과 1]

 

 

 `run`을 이용해서 함수의 scope 안에서 새로운 scope를 만들어서 사용할 수 있다. 당연히 `run` scope의 상위 scope에 있는 값들을 사용할 수 있고, 안에서 새로 만들어서 사용할 수도 있다. scope가 새로 생긴 것이기 때문에 변수 이름을 중첩하여도 에러가 발생하지는 않는다. 반복문 등 어떠한 scope 안에서 생성한 값들은 해당 scope 밖에서는 사용할 수 없는 것과 동일하게 `run` scope 안에서 생성한 것들도 밖에서는 접근이 불가능하다.

 

[예시 코드 2]

 

 

[실행 결과 2]

 

 

 `run`의 scope는 마지막 object를 반환하기 때문에 위와 같은 동작도 가능하다.

 

 

Scoping Function - "with", "T.run"

[예시 코드 1]

 

 

[실행 결과 1]

 

 

 `with`와 `T.run`의 scope 내부 동작은 동일하다. 위와 같은 경우에는 다를 것이 전혀 없어 보이지만 개인적으로는 `T.run`을 사용하는 것이 더 낫다고 생각한다. 다음의 예시 2를 보면 그 이유를 알 수 있다.

 

[예시 코드 2]

 

 

 위와 같이 `with`나 `T.run`을 사용하는 대상이 Nullable 타입이라면 사용하는 모습이 약간 다르다. `with`의 경우는 안에서 사용할 때마다 nullable 체크를 해주며 사용해야 하고, `T.run`의 경우는 처음에 `run`을 호출할 때 한번만 `?.` 연산자를 사용하면 된다. 해당 오브젝트가 null일 때도 오브젝트와 관계 없이 무언가가 실행되어야 한다면 `with`를 사용할 수 있겠지만 그로 인해 다른 부분들에 있어서 계속하여 체크를 해주어야 하기 때문에 그런 경우에도 그냥 `T.run`을 사용하고 밖에서 따로 처리를 해주는 것이 좋다고 생각한다. `with`보다는 `T.run`을 많이 사용할 것 같다.

 

 

Scoping Function - "T.run",  "T.let"

위와 같이 사용해보면 `T.run`의 경우는 this로 받고, `T.let`의 경우는 it으로 받게 된다. 예시 코드를 보며 좀 더 자세히 살펴보자.

 

[예시 코드]

 

 

[실행 결과]

 

 

 `T.run`과 `T.let`도 기본적인 동작은 서로 유사해 보인다. 다만, `T.run`은 argument를 `this`로 받고, `T.let`은 argument를 일반적인 closure)처럼 `it`으로 받는다.

 

 

Scoping Function - "T.let", "T.also"

[예시 코드 1]

 

 

[실행 결과 1]

 

 

 scope 안쪽에서의 동작은 둘 다 동일하다. lamda 형식으로 it이나, 직접 설정한 변수 이름을 받아서 사용할 수 있다. 하지만 반환하는 부분에 있어서 둘은 다르게 동작하는데 이 부분은 예시 2를 보면 확인할 수 있다.

 

[예시 코드 2]

 

 

[실행 결과 2]

 

 

 `T.let`의 경우 기존과 다른 타입을 반환할 수 있다. 위와 같이 chaining을 이용하여 원하는 작업을 쭉 수행할 수 있다.

 

[예시 코드 3]

 

 

[실행 결과 3]

 

 

 예시 2와 모두 동일하지만 `T.let` 대신 `T.also`를 사용한 결과이다. scope 내에서 반환하려고 했던 것들이 사용되지 않고 모두 기존의 값이 그대로 넘어간 것을 확인할 수 있다. `T.also`는 이름과 같이 기존의 값에 대해서 chaining을 걸어서 사용할 때 쓸 수 있다. 물론 위와 같이 한 scope에서 모두 처리해도 상관 없는 것들은 굳이 also로 여러 번 사용하지 않아도 되지만, 복잡한 과정에서 process들을 구분지어줄 때 깔끔해 보이도록 할 수 있는 장점이 있다. 또 chaing 과정 속에서 무언가 동작을 해서 변형된 결과를 넘겨줄 때도 코드가 더 깔끔해질 수 있는 장점도 있다. 두 가지를 섞어서 적절히 사용하면 좋을 것이다.

 

 

Scoping Function - "T.apply"

[예시 코드]

 

 

 `T.apply`는 argument로 this를 받고, this를 return한다. 그렇기에 scope 안에서 변경되는 작업들을 진행할 수 있다. 이를 이용하면 위의 예시 코드와 같이 코드를 간결하게 만들 수 있는 장점이 있다. 물론 이를 이용하여 chaing도 가능하다.

 

 

적절한 scope function 선택

 앞서 확인한 scoping function들 중 언제 어떤 것을 써야 할지를 정리하였다. 위와 같은 기준들로 필요한 scoping scope를 선택하여 그때그때 알맞게 사용하면 된다.

 

 

반응형

댓글