728x90
스코프 함수 (Scope Function) ?
- 코틀린에서는 스코프 함수라는 특별한 종류의 함수가 있습니다. 이 함수들은 객체의 범위 내에서 코드 블록을 실행하며, 주로 객체 초기화, 속성 설정, 연산 후 결과 반환 등의 작업에 사용됩니다.
- 객체의 이름을 통해 하나하나 참조하지 않고 객체를 접근하고 핸들링 할 수 있는 장점이 있습니다.
- 주요한 코틀린 스코프 함수에는 let, run, with, apply, also 다섯 가지가 있습니다.
let
- let 함수는 수신 객체를 람다 함수의 인자로 전달하고, 람다 함수의 결과를 반환합니다.
주로 null 체크 후에 안전하게 수행해야 할 작업이 있을 때 사용됩니다.
data class Person(var name: String, var age: Int)
val person = Person("John", 25).let { p ->
// 객체 초기화와 속성 설정
p.age += 5
p.name = "John Doe"
// let 블록의 마지막 표현식은 반환값으로 사용됨
p
}
- 객체 초기화 및 속성 설정시 사용할 수 있습니다.
val numbers = mutableListOf("one", "two", "three", "four", "five")
numbers.map { it.length }.filter { it > 3 }.let {
println(it)
// 추가적인 함수 호출
val sum = it.sum()
println("Sum of lengths: $sum")
}
- 추가로 함수 호출도 가능합니다.
with
- 주로 수신 객체의 메소드나 속성에 직접 접근하는데 사용됩니다. with를 사용하면 코드 블록 내에서 수신 객체의 멤버에 더 편리하게 접근할 수 있습니다.
data class Person(var name: String, var age: Int)
fun main() {
val person = Person("John", 30)
val result = with(person) {
// 이 블록에서는 person의 멤버에 직접 접근할 수 있음
println("Person's name: $name, age: $age")
// 코드 블록의 마지막 표현식은 반환값으로 사용됨
"$name is $age years old."
}
println(result) // 출력: "John is 30 years old."
}
- with 함수를 사용하면 특정 객체의 멤버에 접근할 때 객체 이름을 반복해서 쓰지 않아도 되기 때문에 코드를 더 간결하게 작성할 수 있습니다.
val numbers = listOf(1, 2, 3, 4, 5)
val filteredNumbers = with(numbers) {
// 리스트의 filter() 함수에 접근하여 필터링
this.filter { it % 2 == 0 }
}
println(filteredNumbers)
- with 함수 내에서 this를 사용하여 수신 객체의 멤버에 직접 접근하고 있습니다. with를 사용하면 여러 메소드나 속성에 접근할 때 특히 코드를 더 간결하게 유지할 수 있습니다.
run
- 주로 객체의 초기화와 함께 코드 블록을 실행하고자 할 때 사용됩니다. run 함수는 수신 객체를 람다 함수의 수신자로 전달하고, 람다 함수의 결과는 코드 블록의 마지막 표현식이 됩니다.
data class Person(var name: String, var age: Int)
fun main() {
val person = Person("John", 30)
val result = person.run {
// 이 블록에서는 person의 멤버에 직접 접근할 수 있음
println("Person's name: $name, age: $age")
// 코드 블록의 마지막 표현식은 반환값으로 사용됨
"$name is $age years old."
}
println(result) // 출력: "John is 30 years old."
}
- run 함수를 사용하면 특정 객체의 멤버에 접근할 때 객체 이름을 반복해서 쓰지 않아도 되기 때문에 코드를 더 간결하게 작성할 수 있습니다.
class Car(var brand: String, var model: String, var year: Int)
fun main() {
val myCar = Car("Toyota", "Camry", 2022).run {
// 객체 초기화와 속성 가공
this.year += 1
"My car is a $brand $model from the year $year."
}
println(myCar)
}
- this 키워드를 사용하여 현재 수신 객체에 접근하고, year 속성을 증가시킵니다.
apply
- 수신 객체를 초기화하고 수정하는데 사용됩니다. 주로 객체를 생성하면서 여러 속성을 초기화할 때 유용하게 활용됩니다.
- apply 함수의 특징은 람다 블록 내에서 수신 객체의 멤버에 직접 접근할 수 있다는 것입니다. 블록의 마지막 표현식은 수신 객체 자체이며, 반환값은 수신 객체입니다.
class Car(var brand: String, var model: String, var year: Int)
fun main() {
val myCar = Car("Toyota", "Camry", 2022).apply {
// 객체 초기화 및 속성 가공
year += 1
// 다른 속성 초기화 가능
}
println("My car is a ${myCar.brand} ${myCar.model} from the year ${myCar.year}.")
}
- apply 함수를 사용하여 Car 클래스의 인스턴스를 초기화하고, 블록 내에서 year 속성을 증가시켰습니다. 이렇게 하면 객체를 생성하면서 속성을 초기화할 때 코드를 더 간결하게 유지할 수 있습니다.
class Movie(var title: String, var genre: String, var releaseYear: Int)
val movie = Movie("", "", 0).apply {
// 객체의 속성 초기화 및 가공
this.title = "Inception"
this.genre = "Sci-Fi"
this.releaseYear = 2010
}
println("Movie details: ${movie.title}, ${movie.genre}, released in ${movie.releaseYear}.")
- apply 함수 내에서 this를 사용하여 수신된 객체의 멤버에 직접 접근하고 있습니다. this를 사용하면 객체의 속성에 더 명시적으로 접근할 수 있으며 코드를 더 명확하게 만들 수 있습니다.
also
- 수신 객체를 그대로 반환하면서, 람다 블록 내에서 수신 객체를 사용하여 원하는 작업을 수행합니다.
- also 함수의 특징은 람다 블록 내에서 수신 객체를 it이라는 이름으로 사용할 수 있다는 것입니다. 블록 내에서의 작업이 주로 로깅, 추가적인 처리, 또는 디버깅과 같은 목적으로 활용됩니다.
class Person(var name: String, var age: Int)
fun main() {
val person = Person("Alice", 25).also {
// also 블록 내에서 수신 객체에 작업 수행
it.age += 5
println("Person details inside 'also': ${it.name}, ${it.age} years old.")
}
println("Person details outside 'also': ${person.name}, ${person.age} years old.")
}
- also 함수를 사용하여 Person 클래스의 인스턴스를 초기화하고, 블록 내에서 age 속성을 수정하고 출력합니다. 이후에도 also 블록 이후의 코드에서 person 객체를 사용할 수 있습니다.
class Book(var title: String, var author: String, var pageCount: Int)
val myBook = Book("", "", 0).also {
// 블록 내에서 it을 사용하여 객체의 속성 초기화
it.title = "The Catcher in the Rye"
it.author = "J.D. Salinger"
it.pageCount = 224
}
println("Book details: ${myBook.title} by ${myBook.author}, ${myBook.pageCount} pages.")
- also 함수를 사용하여 객체를 초기화하고 속성을 설정하며, 블록 내에서 it을 활용하여 수신 객체에 직접 접근하고 있습니다. 이렇게 함으로써 코드를 더 간결하게 작성하고 가독성을 높일 수 있습니다.
This? It?
This
- this는 클래스나 확장 함수 내에서 현재 객체에 대한 참조를 나타냅니다.
- 클래스의 멤버 함수나 클래스 내부에서 this를 사용하면 그것은 현재 객체를 가리킵니다.
It
- it은 람다 함수 블록 내에서 수신된 객체를 참조하는 데 사용됩니다.
- it은 이름이 고정되어 있으며 블록 내에서 수신된 객체에 직접 접근할 때 사용됩니다.
함수 | 키워드 |
let | it |
with | this |
run | this |
apply | this |
also | it |
차이점
let
- 사용 목적: 람다 블록을 수행하면서 결과 값을 반환하고자 할 때 사용합니다.
사용 시점: Nullable 객체에 대한 작업을 수행하고 결과를 반환하거나, 체이닝된 호출을 할 때 사용합니다.
with
- 사용 목적: 특정 객체에 대한 코드 블록을 실행하면서 그 객체의 멤버에 직접 접근하고자 할 때 사용합니다.
사용 시점: 객체의 멤버에 접근하는 코드를 좀 더 간결하게 표현하고자 할 때 사용합니다.
run
- 사용 목적: 특정 객체에 대한 코드 블록을 실행하면서 그 객체의 멤버에 접근하고자 할 때 사용합니다. let과 유사하지만, 확장 함수 형태로 사용되어 더 명시적인 코드를 작성할 때 주로 활용됩니다.
사용 시점: 객체의 초기화 또는 연산을 수행하면서 결과 값을 반환하고자 할 때 사용합니다.
apply
- 사용 목적: 특정 객체의 속성을 초기화하거나 수정하면서 그 객체 자체를 반환하고자 할 때 사용합니다.
사용 시점: 객체의 속성을 초기화하거나 수정하는 작업을 수행하면서 객체 자체를 반환하고자 할 때 사용합니다.
also
- 사용 목적: 특정 객체에 대한 작업을 수행하면서 그 객체 자체를 반환하고자 할 때 사용합니다. apply와 유사하지만, 블록 내에서 it 키워드를 사용하여 더 명시적으로 객체에 접근할 수 있습니다.
사용 시점: 객체에 대한 부가적인 작업을 수행하면서 객체 자체를 반환하고자 할 때 사용합니다.
728x90
반응형
'Kotlin Language > Kotlin 기본 문법' 카테고리의 다른 글
Kotlin(코틀린) - 확장함수(Extension functions) (0) | 2023.12.07 |
---|---|
Kotlin(코틀린) - 지연 초기화(lateinit , lazy) (0) | 2023.12.07 |
Kotlin(코틀린) - 오버라이딩(Overriding) (0) | 2023.12.06 |
Kotlin(코틀린) - 고차함수(Higher-order Function) (0) | 2023.12.06 |
Kotlin(코틀린) - 널 안전성 (Null-Safety) (0) | 2023.12.05 |
Kotiln(코틀린) - 예외처리(try catch,throw) (0) | 2023.12.05 |