[Kotlin] Scope 함수

mi-fasol·2023년 1월 26일
0

Kotlin

목록 보기
1/5

해당 게시물은 과거에 작성한 블로그 내용을 옮겨 온 것으로, 가독성이 떨어지고 내용이 부정확할 수 있습니다.

스코프 함수 (Scope Function)

  • 특정 객체의 context에서 특정한 동작을 수행하기 위한 목적을 가지는 함수
  • 스코프 함수를 람다 함수로 사용할 시 임시 스코프를 형성
    • 객체의 이름을 반복 선언하지 않아도 객체에 접근 및 관리 가능
  • 코틀린에서 제공하는 스코프 함수의 종류는 5가지
    • let
    • also
    • apply
    • with
    • run
Scope FunctionContext Objectreturn value
letitlambda result
alsoitcontext object
applythiscontext object
withthiscontext object
runthislambda result

let

  • it 키워드를 사용
  • 변수명을 반복 사용하지 않을 수 있도록 작성 가능
  • 컨텍스트 객체의 반환 값은 람다 결과 값과 동일
  • 호출 체인의 결과로 하나 이상의 함수를 invoke 할 때 유용
  • ?.let { ... } 블록 내에는 non-null 값만 사용 가능
class User(var userName : String, var grade : Int){
    fun increaseGrade() = grade++     // User의 grade를 1씩 증가
}

User("minyoong", 3).let{
    print("${it.grade}, ")
    it.increaseGrade()
    println(it.grade)
}
  • 출력값: 3, 4
  • let을 사용하지 않고 작성하려면 grade라는 변수명이 반복되어 코드를 보기에 어지러웠을 것

also

  • it 키워드를 사용
  • 객체의 수정이 아닌 추가적으로 다른 일을 하고 싶을 때 사용
  • 컨텍스트 객체의 반환 값은 객체 자신과 동일
var grade = 3

fun getAndIncreaseGrade() = number.also{
    grade++     // 우선 함수를 실행한 후 마지막에 grade에 1 증가
}

fun main(){
    println("before grade: ${getAndIcreaseGrade()}")
    println("after grade: ${getAndIncreaseGrade()"}
}
  • 출력 값
    before grade: 3
    after grade: 4

apply

  • this 키워드를 사용
  • 이름 없이 객체에 접근 가능
  • 컨텍스트 객체의 반환 값은 객체 자신과 동일
class User{
    constructor(userName : String, grade : Int){
        this.userName = userName
        this.grade = grade
    }

    constructor(userName : String){
        this.userName = userName
    }
    
    var userName : String? = null
    var grade = 3
}

fun main(){
    val who = User("mifasol").apply{
        grade = 3
    }
    println("${who.userName}")
}
  • 출력값 : mifasol
  • apply를 사용함으로써 객체 이름을 생략하고 grade 값에 접근하여 값 설정

with

  • this 키워드를 사용
  • 해당 객체를 가지고 다음의 어떤 동작을 할 때 사용
  • 컨텍스트 객체의 반환 값은 람다의 결과
fun main(){
    val userName = mutableListOf("mifasol", "IE", "haribo")
    with(userName){
        println("userName List: $this")
        println("They have $size users.")
    }
} 
  • 출력값
    userName List : [mifasol, IE, haribo]
    They have 3 users.
  • this 키워드를 사용하여 간단히 userName의 요소들 출력

run

  • this 키워드를 사용
  • with와 비슷한 동작을 하지만 다르게 확장 함수
  • ?.run{ ... } 블록 내에는 non-null 값만 사용 가능
  • 어떤 값을 계산하거나 여러 지역 변수의 범위를 제한할 때 사용 가능
  • 매개 변수로 전달된 명시적인 수신 객체를 암시적으로 변환할 때 사용 가능
  • 어떤 객체를 생성하는 명령문을 블록 안에 넣어 높은 가독성을 원할 때 사용 가능
val user = run{     // expression이 필요한 여러 줄의 코드를 한꺼번에 처리 가능, 높은 가독성
    val userName = "minyoong"
    val grade = 3
    
    User(userName, grade)
}

// 또는

val myUser = User("minyoong", 3)     // grade 값을 계산
val newGrade = myUser.run{
    ++grade     // grade에 먼저 1 증가
}

println("$newGrade")

// 또는

fun getGrade (user : User) = user.run{     // user을 수신 객체로 변환 후 grade 사용
    print(grade)
}
  • 두 번째 코드의 출력값 : 4
  • 세 번째 코드의 출력값 : 3
profile
정위블

0개의 댓글