[안드로이드][Kotlin] Scope Functions (Apply, Also, Let, With, Run 함수)
코틀린 표준 라이브러리에서는 자기 자신의 객체를 전달하는 Scope Function 을 지원한다.
Scope Funtion에는 크게 Apply, Also, Let, With, Run 함수가 존재한다.
아래 표를 통해 전체적인 그림에 대해 알아보자.
접근방식 this | 접근방식 it | |
객체 자신을 반환 | apply | also |
블록 수행 결과를 반환 | run, with | let |
본 게시물에서는 5가지 Scope Function 의 정의를 포함한 Java VS Kotlin 코드를 비교하여 다뤄볼 예정이다.
1. Apply 함수
this 를 통해 자신의 객체를 전달하고 그 객체를 다시 반환하는 함수로, 주로 객체의 상태를 변화시키고 바로 저장하고 싶을 때 사용하는 함수이다.
//Kotlin Code
val person = Person.apply {
firstName = "Hong"
lastName = "Gildong"
}
//Java Code
Person person = new Person();
person.firstName = "Hong";
person.lastName = "Gildong";
2. Also 함수
apply 함수와 마찬가지로 객체를 반환하지만, apply 함수와 달리 it으로 자신의 객체를 전달하고 객체를 반환한다. 또한 객체가 파라미터를 통해 전달된다는 차이점이 있다. (람다의 입력값이 되어 it으로 접근이 가능)
//Kotlin Code
Random.nextInt(100).also {
print("value : $it")
}
//위 코드와 같은 의미. (it 대신 value를 람다의 입력값으로 사용)
Random.nextInt(100).also { value ->
print("value : $value")
}
//Java Code
int value = Random().nextInt(100);
System.out.print(value);
3. Let 함수
null이 아닌 객체에서 람다를 사용할 때 주로 사용하는 함수로, let 함수 안에서 수행했던 결과값을 반환한다.
?.let 을 실행하면 let 안으로 들어오는 변수의 내용은 절대로 null 이 아님을 보장한다.
//Kotlin Code
val number: Int?
val sumNumberStr = number?.let {
"${sum(10, it)}"
}.orEmpty() //orEmpty()는 String이 Nullable일때만 사용 가능
//null이 들어와서 let 함수가 실행이 안되면 sumNumberStr은 null이 아니라 빈값임
//Java Code
Integer number = null;
String sumNumberStr = null;
if(number != null) {
sumNumberStr = "" + sum(10, number);
} else {
sumNumberStr = "";
}
4. With 함수
"이 객체를 통해서는 이런것을 할 수 있다" 라고 표현할 때 사용하는 함수로, with 함수의 반환값은 람다의 결과값이다.
with 함수는 this로 자신의 객체를 전달하는데, this를 생략할 수 있기 때문에 반드시 null이 아닐때만 사용하는것이 좋다.
//Kotlin Code
val person = Person()
with(person) {
work()
sleep()
}
//Java Code
Person person = new Person();
person.work();
person.sleep();
5. Run 함수
with 함수는 null이 아님을 보장할 때만 사용이 가능한 반면, run 함수는 null 체크를 수행할 수 있기 때문에 보다 안정성이 높다. 또한 this로 들어온다는 with 함수와의 비슷한 특징이 있긴 하지만, with 함수는 확장함수로 사용이 불가하지만 run 함수는 확장함수로도 사용이 가능하다.
어떤 값을 계산할 필요가 있거나, 초기화와 결과 계산이 동시에 있을 때 사용하기 유용한 함수이다.
//Kotlin Code
val result = service.run {
port = 8080
query()
}
//Java Code
service.port = 8080;
Result result = service.query();