[kotlin] Scope functions | 범위 지정 함수

Happy Jiwon·2024년 1월 24일
1

Kotlin

목록 보기
6/6

범위 지정 함수(Scope functions)란?

특정 객체에 대한 작업을 블록 안에 넣어 실행할 수 있도록 하는 여러 함수가 포함되어 있다. 제공된 람다식이 이는 개체에서 apply, let, run, with, also 총 5가지 함수를 호출하면 임시 범위가 형성된다.

apply

수신 객체 내부 프로퍼티를 변경한 다음 수신 객체 자체를 반환하기 위해 사용되는 함수이다.

public inline fun <T> T.apply(block: T.() -> Unit): T 

T.apply 에서 T 는 apply의 수신 객체
block: T 에서 T 는 람다의 수신 객체

apply는 컨텍스트 개체 자체를 반환하므로 값을 반환하지 않고 주로 수신자 개체의 멤버에 대해 작동하는 코드 블록에 사용하는 것이 좋다.

val jw = Person("Jiwon").apply {
    age = 32 
    city = "Seoul"        
}
println(jw)

프로퍼티 설정할 때마다 person을 쓰지 않고 사용 가능하여 가독성이 좋다.

// 기존의 Person 클래스 초기화 방법
val person = Person()
person.name = "Jiwon"
person.city = "Seoul"

let

fun <T, R> T.let(block: (T) -> R): R

let 함수는 매개변수화된 타입 T의 확장 함수이다.
자기 자신을 받아서 R을 반환하는((T) -> R) 람다 식을 입력으로 받고, 블럭 함수의 반환값 R을 반환한다. 여기서는 Person 클래스의 확장 함수로 사용되어 person.let 의 형태가 가능해진다.

let 함수를 사용하면 객체의 상태를 변경할 수 있다.

val result = person.let {
    it.name = "Jiwon"
    it.age = 24
    it // (T)->R 부분에서의 R에 해당하는 반환 값
}

with

with는 일반 함수로, 객체를 파라미터로 직접 입력 받고, 객체를 사용하기 위한 람다 블록을 받는다.

fun <T, R> with(receiver: T, block: T.() -> R): R

receiver 로 객체를 입력받으면, it 이나 this 등 키워드 없이 객체의 속성을 참조하거나 변경할 수 있다.

val result = Person("Jiwon", 24)

with(result) {
    println(name)
    println(age)
}

// Jiwon
// 24

withnon-null 객체를 이용할 때 사용할 수 있고, 리턴을 할 수 없어 별다른 반환값이 필요하지 않을 때 사용한다.

즉, 객체의 함수나 속성을 여러번 호출할 때 코드들을 그룹핑하는 용도로 활용할 수 있다.


run

1. 첫번째

fun <T, R> T.run(block: T.() -> R): R

with 와 다른 점이라면,T 의 확장함수로 선언되어 있다는 점이다.
확장함수이기 때문에 with 와 다르게 Safe Call 을 붙인다면 null 객체가 들어와도 non-null 검사를 하고 실행할 수 있다.

val result = Person("Jiwon", 24)
val ageNextYear = result.run {
    ++age  // Return
}

println("$ageNextYear")

// 25
// 마지막 실행문의 결과를 반환!!

객체의 특성이나 메소드 등을 활용하여 어떤 값을 계산할 필요가 있거나, 여러 개의 지역변수 범위를 제한하고자 할 때 사용한다.

2. 두번째

fun <R> run(block: () -> R): R

위는 확장함수가 아니고 블록에 입력값도 없다.
이는 객체 속성을 이요하려는 상황에 사용하는 것이 아닌 어떤 객체를 생성하기 위한 실행문들을 하나로 묶어 리더빌리티를 높이는 역할을 수행한다.

val person = run {
    val name = "Jiwon"
    val age = 24
    Person(name, age)  // Return
}

위와 같이 작성하면 Person에 name = Jiwon, age = 24가 저장된다.


also

profile
공부가 조은 안드로이드 개발자

0개의 댓글