티스토리 뷰

반응형

코틀린에서 기본적으로 제공하는 범위 함수에 대해 알아봅니다.

 

람다식을 사용해서 호출하면, 람다 안에서 일시적으로 범위가 형성됩니다. 이 범위 안에서 람다를 부른 객체 등에 자유롭게 접근이 가능합니다. 범위 함수는 코드를 좀 더 간결하고, 읽기 쉽게 만들어줍니다. 여러 종류의 범위 함수를 확인해 봅시다.

 

1. Apply 함수

 

Apply 함수는 객체의 확장 함수이며, 블록 함수를 리시버가 있는 함수 리터럴(Function Literals with Receiver)로 받기 때문에 내부에서는 this를 통해서 객체에 접근할 수 있습니다. 반환 값으로는 이 객체를 다시 반환하게 됩니다.

리시버가 있는 함수 리터럴(Function Literals with Receiver)은 람다에 객체를 축약해서 넘겨주고, 이를 this로 접근할 수 있도록 합니다. this를 통해서 접근할 수 있으므로, this 생략이 가능합니다.

 

아래의 코드를 확인합니다.

val animal = Animal().apply {
   seaAnimal = "Hippo"
   landAnimal = "Tiger"
}

위의 코드에서 seaAnimal과 landAnimal은 this에 포함된 프로퍼티지만, this.seaAnimal로 쓰지 않고 this를 생략했습니다. Apply 함수는 블록 내부에서 객체 프로퍼티에 접근할 수 있으며, 반환 값은 객체 자신이 됩니다. 주로 객체를 초기화하는 경우에 사용됩니다.

반응형

2. Also 함수

 

Also 함수는 Apply 함수와는 다르게 객체가 파라미터로 전달됩니다. 파라미터로 전달되기 때문에, 람다의 입력 값으로 내려오게 됩니다. 람다의 입력 값은 it으로 접근이 가능합니다. 파라미터명을 직접 명시해주거나, 생략하여 it으로 접근할 수 있습니다. Apply 함수와 마찬가지로, 객체를 반환하게 됩니다.

 

아래 코드를 확인합니다.

Random.nextInt(10).also {
   print("임의의 수 결과 값은 $it 입니다.")
}

Random.nextInt(10).also { result ->
   print("임의의 수 결과 값은 $result 입니다.")
}

Random 함수를 통해 10개의 Int 값 중에서 임의 수 하나를 도출 한 후, 다시 Also 함수를 통해서 결과 값을 받게 됩니다. 받을 때 람다의 파라미터명을 정해서 받거나, 생략해서 it으로 받을 수 있습니다.

 

이를 자바 코드로 변경하면 다음과 같습니다.

int result = Random().nextInt(10);
System.out.println(result);

Also 함수는 객체를 람다 입력 값으로 받고 다시 반환하기 때문에, 객체 유효성을 확인하거나, print 함수를 통해서 디버깅하는 용도로 사용됩니다.

 

3. Let 함수

 

Let 함수는 주로 널값이 아닌 객체에서 람다를 실행하는 경우에 사용됩니다. Let 함수는 객체 자신을 반환하는 Apply 및 Also 함수와는 다르게 코드 블럭의 실행 결과 값이 반환됩니다.

NullSafe한 코틀린 문법인 ? 뒤에 Let 함수를 실행하여, 결과 값이 물음표 안으로 들어가게 되어, 넓값이 아닌 객체에서 람다를 실행할 수 있도록 합니다.

 

아래의 코드를 봅니다.

//널값이 가능한 자료형으로 선언
val number: Int?

val totalNumber = number?.let {
  "${sum(100, it)}"
}

val totalNumber = number?.let {
  "${sum(100, it)}"
}.orEmpty()

 

우선 number에 널값이 가능하도록 선언합니다. 

number?.let 부분에서, number 값이 널이면 let 뒤의 코드 블럭이 실행되지 않으며, 널값이 아닌 경우에만 sum 함수가 실행됩니다. 이때 it을 통해서 number의 값을 받아오게 됩니다.

 

orEmpty( ) 함수는 스트링의 멤버 함수 중 하나로 스트링이 Nullable 한 경우에만 사용 가능하며, 널값의 스트링을 널이 아닌 빈 값으로 바꾸는 기능을 합니다. 널값이 넘어오면 빈 값으로 치환하기 때문에, 널값을 예방할 수 있습니다.

 

Let 함수는 널값을 방지하기 위해 자주 사용됩니다.

 

 

4. With 함수

 

With 함수의 반환 값은 람다 함수의 결과 값입니다. 아래의 코드를 확인합니다.

val food = Food()

with(food) {
 snack()
 drink()
 pizza()
}

With 함수는 위의 코드처럼, 객체로도 사용이 가능합니다. 위의 코드는 with(food)를 통해서 food가 가지는 세 가지 함수를 한 번에 실행하고 있습니다. 당연히, food의 함수들을 this를 통해서도 호출할 수 있습니다.

 

With 함수는 food.with 처럼 확장 함수 형태로 사용이 불가능합니다.

 

 

5. Run 함수

 

어떤 값을 계산할 필요가 있거나, 그 객체 구성과 결과 계산이 한 번에 있는 경우 유용합니다. 객체 구성은 초기화를 의미하는데, 초기화 이후에 결과를 바로 계산하거나, 어떤 값을 계산할 때 사용되는 함수입니다. Run 함수는 With 함수처럼, 반환 값이 람다의 결과 값입니다.

 

Run 함수는 With 함수와는 다르게 확장 함수처럼 사용이 가능합니다.

 

 바로 예문을 살펴봅니다.

val result = service.run {
 port = 1004
 query()
}

위의 상황은 1004 포트를 설정하고, 쿼리의 반환 값이 result 변수에 들어가는 예시입니다. 이처럼, 객체 구성이 포트의 초기화를 진행하고, 이후 쿼리 값이 Run 함수를 통해서 람다의 결과 값으로 리턴되게 합니다.

반응형

'Kotlin' 카테고리의 다른 글

람다 표현식 Lamda Expression  (0) 2021.07.09
데이터 클래스 Data Class  (0) 2021.07.08
코틀린 제너릭 Kotlin Generics  (0) 2021.07.06
코틀린 인터페이스 Kotlin Interface  (0) 2021.07.06
코틀린 상속 Kotlin Inheritance  (0) 2021.07.06
댓글