Coding Memo
Kotlin 스코프 함수 본문
스코프 함수 (Scope Function)
Kotlin 기본 라이브러리에서 제공하는 기본 함수로 객체를 직접 생성하지 않고 그 객체의 함수를 사용할 수 있다.
Kotlin의 스코프 함수는 5가지가 있다.
apply
run
with
also
let
각 함수들은 역할이 비슷하다.
apply
apply는 자기 자신을 반환한다.
this. 와 같은 참조 연산자를 따로 사용할 필요가 없다. (하지만 같은 이름의 변수가 있을 수 있으니 붙여서 사용하자)
보통 body 부분에서 값을 초기화하기 위해 사용하며 property(속성)만을 사용한다. (함수 사용 x)
class Book (title: String, price: Int) {
var title: String = title
var price: Int = price
var code: String = ""
fun printInfo() {
println("title: $title, price: $price, code: $code")
}
}
fun main() {
var b = Book("Harry Potter", 10000)
.apply {
title = "Harry Potter and the Chamber of Secrets"
code = "A1B2C3"
}.printInfo()
}
b 객체의 값을 변경할 때 this와 같은 키워드나 참조 연산자를 따로 사용하지 않고 값을 변경했다.
apply 옆에 'this: Book'이 표시되어 있다.
run
apply와 비슷하지만 차이점은 return 값이 this가 아니라 구문이 있는 블록의 return 값이다.
run 블록의 마지막 구문에서 return이 된다.
class Book (title: String, price: Int) {
var title: String = title
var price: Int = price
var type: String = ""
var code: String = ""
fun printInfo() {
println("title: $title, price: $price, code: $code")
}
}
fun main() {
var b = Book("Harry Potter", 10000).apply { type = "Novel" }
if (b.run { (this.type == "Novel") }) {
println("b is novel")
}
}
'b.run { (this.type == "Novel") }'의 결과값이 true 이므로 println()이 실행되었다.
with
run과 하는 일은 같고, 인스턴스를 파라미터로 받는다는 점만 다르다.
즉 b.run{} 과 with(a){}는 같다.
class Book (title: String, price: Int) {
var title: String = title
var price: Int = price
var type: String = ""
fun printInfo() {
println("title: $title, price: $price, type: $type")
}
}
fun main() {
var b = Book("Harry Potter", 10000).apply { type = "Novel" }
var isNovel1: Boolean = with(b) {
type == "Novel"
}
//same as with(b){}
var isNovel2 = b.run { type == "Novel" }
println("isNovel1 = $isNovel1")
println("isNovel2 = $isNovel2")
}
also
간단하게 말하면, apply랑 하는 일은 같지만 파라미터를 인스턴스를 파라미터로 받고 그것을 'it'으로 사용한다.
class Book (title: String, price: Int) {
var title: String = title
var price: Int = price
var type: String = ""
fun printInfo() {
println("title: $title, price: $price, type: $type")
}
}
fun main() {
var b = Book("Harry Potter", 10000)
.also { it.printInfo() }
}
let
run과 같은 역할을 하고 also와 마찬가지로 파라미터로 인스턴스 자신을 받고, 그것을 'it'으로 사용한다.
(run과 같은 역할을 하지만 같은 이름의 변수의 혼란을 방지하기 위해서 사용하기도 한다.)
null 이 아닌 값을 가지는 코드 블록을 실행시킬 때도 let이 쓰인다.
class Book (title: String, price: Int) {
var title: String = title
var price: Int = price
var type: String = ""
fun printInfo() {
println("title: $title, price: $price, type: $type")
}
}
fun main() {
var b = Book("Harry Potter", 10000).apply { type = "Novel" }
var isNovel1: Boolean = with(b) {
type == "Novel"
}
//same as with(b){}
var isNovel2 = b.run { type == "Novel" }
var isNovel3 = b.let { it.type == "Novel" }
println("isNovel1 = $isNovel1")
println("isNovel2 = $isNovel2")
println("isNovel3 = $isNovel3")
}
간단한 특징만 정리한 표는 다음과 같다.
apply | run | with | also | let | |
Context Object | this | it | |||
return | self(this) | block() | self(this) | block() |
return 값
apply, also: 자기 자신 (컨텍스트 객체)
run, with, let: 블록 구문의 반환 값 (람다식의 반환 값)
인터넷에 검색해보면 정말 정말 잘 정리해놓은 글들이 많다.
위의 예시들은 굉장히 간단한 예시이고 좀 더 알고 싶으면 다음의 공식 문서를 확인해보는 것이 좋다.
https://kotlinlang.org/docs/reference/scope-functions.html
Scope Functions - Kotlin Programming Language
kotlinlang.org
스코프 함수는 이것저것 찾아보면서 써 내려갔지만 개념 자체는 쉬워 보여도 활용하기가 어려운 부분처럼 보인다...
'Language > Kotlin' 카테고리의 다른 글
Kotlin 옵저버 패턴 (0) | 2021.01.03 |
---|---|
Kotlin 오브젝트 (0) | 2021.01.03 |
Kotlin 인터페이스 (0) | 2021.01.02 |
Kotlin 고차 함수 / 람다 함수 (0) | 2020.12.31 |
Kotlin 클래스 (0) | 2020.12.30 |