Scope function
- 객체의 이름을 사용하지 않고, 객체에 접근이 가능하게 하는 함수
- 특정 객체에 대한 작업을 블록 안에 넣어 실행할 수 있도록 하는 함수 (feat. kotlinworld)
Function | Object reference | Return value | Is extension function |
let | it | Lambda result | Yes |
run | this | Lambda result | Yes |
run | - | Lambda result | No: called without the context object |
with | this | Lambda result | No: takes the context object as an argument |
apply | this | Object reference | Yes |
also | it | Object reference | Yes |
it
- 람다식 내부에서 사용되는 암시적 변수
- 람다식에서 인자가 하나인 경우 it 을 사용해서 인자를 참조할 수 있다.
this
- 클래스의 인스턴스를 참조하는데 사용된다.
- this 를 사용하여 클래스 내부에서 멤버 변수나 멤버 함수를 참조할 수 있다.
let
inline fun <T, R> T.let(block: (T) -> R): R
- 확장 함수이므로, 객체를 생성해서 할당하기 전에 사용이 가능하다.
- 인자로 Lambda function 을 받기 때문에 곧바로 Lambda function 에 해당하는 코드 블록을 작성할 수 있다.
- Lambda function 에 인자를 명시적으로 전달하기 때문에 인자를 it 이나 다른 이름을 부여해 참조가 가능하다.
- 반환 값이 Lambda Result 이다. 임의로 생성한 값이나 객체를 반환할 수 있다.
- 객체를 생성하거나 사용하는 시점에서 다양한 작업을 수행시킨 후 결과를 반환받고 싶을 때, 명시적인 네이밍이 필요할 때 유용하다.
val firstPerson = Person(
email = "firstPerson@gmail.com",
age = 28,
)
val secondPerson = Person(
email = "secondPerson@email.com",
age = 58,
)
val people = listOf(firstPerson, secondPerson)
val firstPersonEmailDoubleLength = people.first()
.let { firstPerson ->
val secondPerson = Person(
email = "wow@wow.com",
age = 10,
)
firstPerson.email.length * 2
}
- mutable 변수의 null check 를 진행하고 싶을 때 유용하다.
private var str: String? = null
fun process() {
if (str != null) {
println(str?.length)
}
}
private var str: String? = null
fun process() {
str?.let { println(it.length) }
}
- nullable 체이닝을 끊어내고 싶을 때 유용하다.
fun process(string: String?): List? {
return string?.asIterable()?.distinct()?.sorted()
}
@Nullable
public final List process(@Nullable String string) {
List var2;
if (string != null) {
Iterable var10000 = StringsKt.asIterable(
(CharSequence)string);
if (var10000 != null) {
var2 = CollectionsKt.distinct(var10000);
if (var2 != null) {
var2 = CollectionsKt.sorted((Iterable)var2);
return var2;
}
}
}
var2 = null;
return var2;
}
fun process(string: String?): List? {
return string?.let {
it.asIterable().distinct().sorted()
}
}
@Nullable
public final List process(@Nullable String string) {
List var10000;
if (string != null) {
int var4 = false;
var10000 = CollectionsKt.sorted(
(Iterable)CollectionsKt.distinct(
StringsKt.asIterable((CharSequence)string)));
} else {
var10000 = null;
}
return var10000;
}
- var4
- 추가 변수
- 초당 수천 번 호출되는 루프에선 문제가 될 수도 있다.
- null check 를 진행한다. if 블럭 내부에서 non null 로 auto-cast 되기 때문에 추가적으로 null check 를 진행할 필요도 없다.
- boolean 은 그다지 비용이 큰 자료형이 아니며 kotlin proguard 를 사용하는 경우 자동으로 제거된다는 의견도 있다.
run
inline fun <R> run(block: () -> R): R
inline fun <T, R> T.run(block: T.() -> R): R
- 단일 lambda function 을 인자로 받는 버전과 확장 함수로 이루어진 버전이 있다.
- 인자로 Lambda function 을 받기 때문에 곧바로 Lambda function 에 해당하는 코드 블록을 작성할 수 있다.
- with 와 유사하지만, run 은 확장 함수 버전 때문에 객체를 생성해서 할당하기 전에 사용이 가능하다는 차이가 생긴다.
- 두 경우 모두 반환 값이 Lambda Result 이다. 임의로 생성한 값이나 객체를 반환할 수 있다.
- 객체를 생성하거나 사용하는 시점에서 다양한 작업을 수행시킨 후 결과를 반환받고 싶을 때 유용하다.
val nameDoubleLength = Person.withDefaultName()
.run { name.length * 2 }
with
inline fun <T, R> with(receiver: T, block: T.() -> R): R
- 확장 함수가 아니다. 객체를 인자로 전달받아 사용한다.
- 두 번째 인자로 람다 함수를 받기 때문에 곧바로 Lambda function 에 해당하는 코드 블록을 작성할 수 있다.
- Lambda function 은 확장 함수 형태로 코드 블록 내에 수신 객체가 암시적으로 전달된다. this 를 이용해 참조한다.
- 반환 값이 Lambda Result 이다. 임의로 생성한 값이나 객체를 반환할 수 있다.
- 이미 생성된 객체에 일괄적인 작업을 처리할 때 유용하다.
val result = with(person) {
isCool = true
isAwesome = true
koreanName = “현구막"
"nice"
}
apply
inline fun <T> T.apply(block: T.() -> Unit): T
- 확장 함수이므로, 객체를 생성해서 할당하기 전에 사용이 가능하다.
- 인자로 Lambda function 을 받기 때문에 곧바로 Lambda function 에 해당하는 코드 블록을 작성할 수 있다.
- Lambda function 은 확장 함수 형태로 코드 블록 내에 수신 객체가 암시적으로 전달된다. this 를 이용해 참조한다.
- 반환 값이 Object reference 이다. 코드 블록 내에 전달된 수신객체를 그대로 다시 반환한다.
- 코드 블록이 모두 수행된 후 인스턴스가 할당되기 때문에 객체 생성시점에서 초기화를 할 때 유용하다.
val person = Person(
email = "aaa@gmail.com",
age = 28,
).apply { name = "홍길동" }
also
inline fun <T> T.also(block: (T) -> Unit): T
- 확장 함수이므로, 객체를 생성해서 할당하기 전에 사용이 가능하다.
- 인자로 Lambda function 을 받기 때문에 곧바로 Lambda function 에 해당하는 코드 블록을 작성할 수 있다.
- Lambda function 에 인자를 명시적으로 전달하기 때문에 인자를 it 이나 다른 이름을 부여해 참조가 가능하다.
- 반환 값이 Object reference 이다. 코드 블록 내에 전달된 수신객체를 그대로 다시 반환한다.
- 이름 그대로 객체에게 명령을 내리기 직전에 추가적인(also) 작업을 함께 수행시키고 싶을 때 유용하다.
val people = listOf(
Person(
email = "firstPerson@gmail.com",
age = 28,
),
Person(
email = "secondPerson@email.com",
age = 58,
)
)
people.first()
.also { firstPerson ->
println("이메일 길이: ${firstPerson.email.length}")
println("현재 나이: ${firstPerson.age}")
}.increaseAge()
'안드로이드 > Kotlin' 카테고리의 다른 글
[Kotlin] 객체 선언(Object Declaration) , 동반 객체(Companion Object) (0) | 2024.12.09 |
---|---|
[Kotlin] 타입 연산자(is, as), 널 처리 연산자 (0) | 2024.12.08 |
[Kotlin] Kotlin 이란 (0) | 2024.12.08 |