- 코틀린에는 scope 함수라는 기능이 있다
그렇지만 이 scope 함수가 많지만 비슷하게 보이는 경우가 많아서 헷갈리는 경우가 많다
오늘은 그래서 scope 함수에 대해서 정리를 해보려고 한다
Scope 함수를 이해가 위해서는 먼저 고차함수와 람다 표현식를 이해하는 것이 좋다
- 고차함수
- 함수를 인자로 받거나 결과 값으로 함수를 반환 할 수 있는 함수
- 고차함수는 function1(100, 100) -> {} 같은 람다 함수 방식으로 표시 할 수 있다
- 또한 :: (함수 참조 연산자(?))를 사용하여 함수를 표현할 수 있다 -> 해당 내용은 다른 포스팅에서 자세하게 다뤄볼 예정입니다
fun addTwoNumbers(number1: Int, number2: Int): Int {
return number1 + number2
}
fun addTenNine(function: (Int, Int) -> Int) {
val result: Int = function(10, 9)
println("결과는 $result 입니다")
}
addTenNine(::addTwoNumbers)
- 람다 표현식
- 항상 중괄호로 묶여서 사용된다
- 매개 변수 선언은 중괄호 안에 들어가며 선택적으로 사용이 가능하다
- 함수의 몸은 -> 다음에 표현한다
// 전체 구문은 이런 방식으로 표현이 된다
val sum: (Int, Int) -> Int = { x: Int, y: Int -> x + y }
// 매개변수의 타입이 명시되있을 경우 람다 표현식 안에 타입을 지정해주지 않아도 된다
val sum: (Int, Int) -> Int = { x, y -> x + y }
// 람다식만 사용할 경우 반드시 타입을 명시해줘야 한다
val sum = { x: Int, y: Int -> x + y }
- Scope 함수
- 객체 블록에 내에서 코드 블록을 실행하는 것이 유일한 목적일 경우 사용이 가능하다
- 객체에서 바로 코드 블록을 실행 할 수 있다는 특징이 있다
- 스코프 함수의 예시
//Person이란 클래스를 해당 값을 받아서 생성할 경우 let을 통해서 바로 실행이 가능하다
Person("Alice", 20, "Amsterdam").let {
println(it)
it.moveTo("London")
it.incrementAge()
println(it)
}
- Scope 함수의 종류
기능 | 참조 객체 | 반환 값 | 확장 가능 여부 |
let | it | 람다의 결과를 반환 | 가능 |
run | this | 람다의 결과를 반환 | 가능 |
run | 람다의 결과를 반환 | Context 객체 없이 호출이 된다 | |
with | this | 람다의 결과를 반환 | Context 객체를 인수로 사용한다 |
apply | this | Context 객체를 반환 | 가능 |
also | it | Context 객체를 반환 | 가능 |
- let
- 타입 T에 대한 확장 함수 -> T에 관한 내용은 다른 포스팅에서 자세하게 다뤄볼 예정입니다
- null이 아닌 객체에 대해서 람다 식으로 실행한다
- ?.(세이프콜)을 활용하여 null인 경우를 처리가 가능하다 -> ?.에 관한 내용은 다른 포스팅에서 자세하게 다뤄볼 예정입니다
- Local 범위의 변수로 표현식을 도입한다
- 람다식 내부의 마지막 줄에 식이 아닌 변수나 객체 단일로 존재할 시, 그 값이 곧 반환값이 된다
getPerson()?.let {
// null 이 아닐때만 실행이 된다
println(it)
}
// 아래의 코드는 let 함수를 쓰지 않고 만든 코드
val person: Person? = getPerson()
if (person != null) {
println(person)
}
- apply
- 값을 수신자로 정해서 지정된 기능 블록을 호출하고 값을 반환하는 함수
- 수신 객체의 함수를 따로 사용하지 않고 수신 객체 자신을 다시 반환하려고 할 경우에 사용한다
- 주로 객체를 초기화 하는 경우에 많이 사용한다
val kim = Person().apply{
name = "Kim"
age = 20
}
//apply 함수를 쓰지 않은 경우
val lee = Person()
lee.name = "lee"
lee.age = 21
- run
- 지정된 블록을 호출하고 결과를 반환하거나 값을 수신자로 해서 지정된 기능 블록을 호출하고 그 결과 값을 반환 한다
- 어떠한 값을 계산하거나 여러개의 지역변수의 범위를 제한 할 필요가 있는 경우 사용한다
- 매개변수로 전달된 명시적 수신 객체를 암시적 수신 객체로 변환 할 때 사용한다
- 객체의 구성 및 결과 계산을 할 경우 사용된다
- also
- T의 확장 함수로서 수신 객체가 암시적으로 제공이 된다
- 수신 객체 지정 람다식에 매개변수 T로 코드 블록 내에 명시적으로 전달된다
- 코드 블록 내에서 전달된 수신 객체를 그대로 다시 반환
- 수신 객체 람다식 내부에서 수신 객체의 함수를 사용하지 않고 수신 객체 자신을 반환하려고 하는 경우에 사용한다
- 주로 추가적인 효과를 구현할 때 사용된다
- with
- 수신 객체가 매개 변수 T로 제공이 된다
- 수신 객체가 지정 람다식이 T의 확장 함수 형태로 코드 블록 내에 수신 객체가 암시적으로 전달된다
- 람다식을 실행한 결과를 반환한다
- Null이 될 수 없는 수신 객체이고 결과가 필요하지 않은 경우에만 사용한다
val person: Person = getPerson()
getPerson.let{
it.name = "Kim"
it.age = 12
}
with(person){
print(name)
print(age)
}
- run과 also는 코드 바로 업데이트 드리겠습니다 감사합니다
'Kotlin' 카테고리의 다른 글
(Kotlin) JPA JPQL orderby 절 적용이 안되는 문제 (0) | 2024.05.21 |
---|---|
(Kotlin) 상수를 다루는 클래스 enum 클래스란?? (0) | 2024.04.30 |
(Kotlin) Interface와 abstract의 차이점 분석 (0) | 2024.04.24 |
(Kotlin) java.lang.unsupportedclassversionerror 애러 해결 (0) | 2024.04.22 |