이번 포스팅에는 Kotlin의 다양한 특징 중 하나인 범위 지정 함수 (Scoping Functions)에 대해서 포스팅할 예정입니다.
Kotlin에서는 객체의 Context내에서 코드의 블럭을 실행하는 것이 유일한 목적인 몇 가지 함수를 가지고 있는데요.
이를 범위 지정 함수라고 부르고, 이러한 함수를 호출한다면 해당 범위 내 임시 스코프가 생성 됩니다.
또한 이 스코프 내에서는 객체의 이름 없이 객체에 엑세스 할 수 있다는 특징이 있습니다.

위 사진에 보이는것과 같이 apply, run, with, also, let의 함수가 존재합니다.
let 지정 함수
val car = Car() /* let을 사용하지 않는 코드 */ if (car.price != null) Toast.makeText(this, car.price, Toast.LENGTH_SHORT).show() /* let을 사용하는 코드 */ car.price?.let { Toast.makeText(this, it, Toast.LENGTH_SHORT).show() }let()을 지정한다면 불필요한 변수의 선언을 변경할 수 있다.
또한 ?을 사용하여 Null값이 아닐 때만 코드를 실행할 수 있다.
만약 Null값일 때 이용해서 코드를 작성한다면 let()을 사용하면 안된다.
also 지정 함수
let()과 굉장히 유사한 구조를 가지고 있습니다.
방금 위에서 사용한 let()과 동일한 구조를 가지는데요.
하지만 차이점은 반환하는 값이 다릅니다.예를 들어서 설명 하겠습니다.
data class Car( var name : String, var price: Int ) val car = Car("tesla", 10000) /* let을 이용한 방법 */ val letFun = car.let { it.name = "tesla Model 3" it.price = 20000 "car change" } println("let() 함수 출력") println(car) println(letFun) val alsoFun = car.also { it.name = "tesla Model Y" it.price = 30000 } println("also() 함수 출력") println(car) println(alsoFun)출력 값
let() 함수 출력
Car(name=tesla Model 3, price=20000)
car changealso() 함수 출력
Car(name=tesla Model Y, price=30000)
Car(name=tesla Model Y, price=30000)let()과 also() 모두 람다식 내의 코드를 처리하지만 반환되는 값의 차이를 보입니다.
let()은 마지막 문장을 반환 결과값으로 저장이되고, also()는 자신의 객체를 반환합니다.
apply 지정 함수
apply() 함수는 also()와 같이 반환되는 값이 자신의 객체 입니다.
두개의 차이점이라고 한다면 apply()는 람다식이 확장함수로 처리 된다는 점이 다릅니다.data class Car( var name : String, var price: Int ) val car = Car("tesla", 10000) car.also { it.name = "tesla Model Y" it.price = 30000 } car.apply { name = "tesla Model S" it.price = 50000 }apply()의 경우 특정 객체를 생성하면서 함께 호출 해야하는 초기화 코드가 있는 경우 많이 사용 됩니다. 예를 들어 Recyclerveiew의 Adapter를 초기화 할때 말이죠.
Run 지정 함수
run() 함수는 인자가 없는 익명의 함수처럼 동작하는 형태. 그리고 객체에서 호출하는 형태. 2가지로 구분 됩니다.val justFun = run { Toast.makeText(this, "그냥 출력 해봤어", Toast.LENGTH_SHORT).show() }위와 같이 인자없이 코드를 실행할 수 있는 블럭으로 생성합니다.
run() 함수는 특정 객체의 조건이 만족 했을 때 추가적인 동작을 사용할 때 사용 됩니다.car?.run { Toast.makeText(this, "객체가 null이 아님", Toast.LENGTH_SHORT).show() }car의 객체가 존재할 때 run 블럭 내의 코드가 추가적으로 동작하는 것을 확인할 수 있습니다.
with 지정 함수
with()의 경우 run() 함수와 기능은 동일하나, 인자로 받는 객체를 이어지는 블록의 리시버로 절당하며, 블록의 결과값을 반환합니다.with(car) { Toast.makeText(this, "객체가 null이 아님", Toast.LENGTH_SHORT).show() }run() 함수와 기능은 동일하게 작동되나, 리시버로 전달될 객체가 어디에 위치하는지만 다르다고 보시면 됩니다.
가치 있는 정보 공유해주셔서 감사합니다.