-
코틀린 apply, also, let, run, with개발/안드로이드 2020. 2. 9. 14:21
자바에 비해 코틀린이 가지는 가장 큰 장점은 코드를 간결하게 작성 할 수 있는 것이라고 생각하는데 모든 객체에 기본적으로 제공하는 범위함수인 apply, also, let, run, with 들이 이 이점을 살리는데 큰 도움이 된다.
이 함수의 차이점에 대해서 설명한 글은 코틀린 공식 문서도 있고 다른 개발 블로그에도 무수히 많지만, 범위 함수에서 강조하는 수신객체와 람다식과 관련된 내용은 문서를 읽는 것 보다는 직접 코드를 짜면서 체험해 볼 때 이해하기가 쉽다. 이번 포스트에서는 apply, also, let, run, with를 언제 사용해야하는지에 대해서 수신객체에 관련된 내용을 제외하고 사용이 필요한 경우만 간략하게 소개해보려고 한다.
1. apply
apply는 객체의 property 값을 적용할 때 사용한다. 어떤 객체를 선언할 때 생성자만으로 값을 세팅할 수 없다면 apply를 통해서 값을 따로 붙여서 연속적으로 값을 세팅할 수 있다. 아래의 두 코드는 모두 동일한 결과를 가지는데 apply 함수를 사용한 경우가 더 명시적이다.
val adam = Person("Adam").apply { age = 20 city = "London" } val adam = Person("Adam") adam.age = 20 adam.city = "London"
2. also
also는 속성 변경을 허용하지 않고 로그를 출력하거나 값의 유효성을 검증하고 싶을 때 사용한다. 아래 코드처럼 also 문 앞에 있는 코드는 property를 바꿀 수 없다. 나도 모르게 저지르는 실수를 사전에 차단하고 싶을 때 사용하면 유용하다.
val numbers = mutableListOf("one", "two", "three") numbers .also { println("The list elements before adding new one: $it") } .add("four")
3. let
객체가 null이 아닌 코드를 실행하는 경우 사용한다. Null pointer 에러로 크래쉬가 나는걸 막을 때 꽤나 유용한 범위함수다. 주로 많이 사용하는 코드다. Java의 Optional.ofNullable 이렇게 길게 쓸 필요가 없어 간결해서 좋다.
val str: String? = "Hello" //processNonNullString(str) // compilation error: str can be null val length = str?.let { println("let() called on $it") processNonNullString(it) // OK: 'it' is not null inside '?.let { }' it.length }
4. run
객체에 포함된 함수를 실행하고 그 결과를 반환할 때 사용한다. 아래 코드를 보면 리스트 타입인 numbers에 포함된 add 함수를 run 내부에서 실행하고 있고 마지막 구문에 e로 끝나는 문자열의 개수를 countEndsWithE 변수에 넣어주고 있다. 실행 결과는 주석으로 처리된 부분을 읽어보면 된다.
나는 이 함수는 자주 사용하지는 않는다. 굳이 함수를 먼저 실행한 다음에 리턴타입이 필요할 일도 없어서. apply랑 비슷한것 같기는 한데 그만한 유용성은 못찾겠다.
val numbers = mutableListOf("one", "two", "three") val countEndsWithE = numbers.run { add("four") add("five") count { it.endsWith("e") } } println("numbers: " + numbers) println("There are $countEndsWithE elements that end with e.") // numbers: [one, two, three, four, five] // There are 3 elements that end with e.
5. with
null이 될 수 없는 객체의 값을 출력할 때 사용한다. also랑 거의 차이가 없어서 나는 잘 사용하지 않는다.
val numbers = mutableListOf("one", "two", "three") with(numbers) { println("'with' is called with argument $this") println("It contains $size elements") }
'개발 > 안드로이드' 카테고리의 다른 글
RxJava: Subject, PublishSubject, BehaviorSubject (0) 2020.02.15 RxJava: defer, fromCallable (0) 2020.02.15 수직으로 스와이프 가능한 ViewPager 만들기 (0) 2019.12.07 RxJava - flatMap (0) 2019.11.30 RxJava - Create 함수 (0) 2019.08.11