20231213 / Scope Functions / let, with, also, apply, run
by jeongminyScope Functions
- 자기 자신의 객체를 전달해서 효율적인 처리를 할 수 있어요
- 객체를 사용할때임시로 Scope를 만들어서 편리한 코드 작성을 도와줘요
코틀린 문서 페이지 : https://kotlinlang.org/docs/scope-functions.html
let
let 함수는 null이 아닌 값에 대해서만 코드 블록을 실행시키기 위해 사용되는 Scope Functions입니다.
중괄호 블록안에 it으로 자신의 객체를 전달하고 수행된 결과를 반환해요
let 함수는 코드의 가독성과 유지보수성을 향상시키는 데 도움이 되는 유용한 함수입니다.
더보기
val car: Car? = null
car?.start()
위 코드는 car 가 null 이기 때문에 실행되지 않는다.
car?.let { it.start() }
그런데, 이 코드는 car가
null이면 -> 아무일도 일어나지 않아!
null이 아니면 -> start() 메소드를 호출함 (왜냐?? let 함수를 이용했기 때문에 it이 car의 값을 참조하게 되서!!)
따라서 위 코드는 아래의 코드와 동일하다고 할 수 있어.
car?.let {
if (it != null) {
it.start()
}
}
with
중괄호 블록안에 this로 자신의 객체를 전달하고 코드를 수행해요
this는 생략해서 사용할 수 있으므로 반드시 null이 아닐때만 사용하는게 좋아요
더보기
var alphabets = "abcd"
with(alphabets) {
// var result = this.subSequence(0,2) // this가 생략되어 있음을 설명
var result = subSequence(0,2) // 아래처럼 쓰임
println(result)
}
also
중괄호 블록안에 it으로 자신의 객체를 전달하고 객체를 반환해줘요
apply와 함께 자주 사용해요
더보기
fun main() {
var student = Student("참새", 10)
var result = student?.also {
it.age = 50 // also를 통해 it이 student객체를 받고, student객체를 반환함.
}
result?.displayInfo() // 출력 : 이름은 참새 입니다 나이는 50 입니다
student.displayInfo() // 출력 : 이름은 참새 입니다 나이는 50 입니다
} // 두 출력이 동일하다는 것은 it이 student 객체를 반환함을 알려줌.
class Student(name: String, age: Int) {
var name: String
var age: Int
init {
this.name = name
this.age = age
}
fun displayInfo() {
println("이름은 ${name} 입니다")
println("나이는 ${age} 입니다")
}
}
apply
중괄호 블록안에 this로 자신의 객체를 전달하고 객체를 반환해줘요
주로 객체의 상태를 변화시키고 바로 저장하고 싶을때 사용해요
더보기
fun main() {
var student = Student("참새", 10)
var result = student?.apply { //apply가 사용됨
student.age = 50 // this가 생략되어 있음
}
result?.displayInfo() // 출력 : 이름은 참새 입니다 나이는 50 입니다
student.displayInfo() // 출력 : 이름은 참새 입니다 나이는 50 입니다
} // 위와 아래가 같음을 확인할 수 있다.
class Student(name: String, age: Int) { //Student클래스 정의
var name: String
var age: Int
init { // 클래스의 생성자
this.name = name
this.age = age
}
fun displayInfo() { //클래스의 메소드
println("이름은 ${name} 입니다")
println("나이는 ${age} 입니다")
}
}
run
run은 객체를 전달받아 처리하는 함수입니다.
run 함수는 객체를 it 으로 받아 사용할 수 있으며, 마지막으로 실행된 코드의 결과를 반환합니다.
1. 객체에서 호출하지 않는 경우의 예시
더보기
fun main() {
var totalPrice = run { // run으로 중괄호안에 임시 영역을 만들고
var computer = 10000 // 변수 두개를 정의하고
var mouse = 5000
computer+mouse // 두개를 더한것을 리턴해서 totalPrice에 넣어라
}
println("총 가격은 ${totalPrice}입니다")
}
2. 객체에서 호출하는 경우의 예시
- with와 달리 null체크를 수행할 수 있어서 더욱 안전 사용 가능
더보기
fun main() {
var student = Student("참새", 10)
student?.run {
displayInfo()
}
}
class Student(name: String, age: Int) {
var name: String
var age: Int
init {
this.name = name
this.age = age
}
fun displayInfo() {
println("이름은 ${name} 입니다")
println("나이는 ${age} 입니다")
}
}
정리
Kotlin에서 let, with, also, apply, run은 모두 scope function으로, 객체의 속성이나 함수를 처리하는 데 사용됩니다.
함수 | 설명 |
let |
객체의 속성이나 함수를 처리하는 람다를 제공합니다. 람다의 반환값은 객체 자체입니다.
|
with |
객체의 속성이나 함수를 처리하는 람다를 제공합니다. 람다의 반환값은 없습니다.
|
also |
객체의 속성이나 함수를 처리하는 람다를 제공합니다. 람다의 반환값은 객체 자체입니다.
|
apply |
객체의 속성이나 함수를 처리하는 람다를 제공합니다. 람다의 반환값은 객체 자체입니다.
|
run |
객체의 속성이나 함수를 처리하는 람다를 제공합니다. 람다의 반환값은 람다 내부의 표현식의 값입니다.
|
Scope에서 접근방식 this |
Scope에서 접근방식 it
|
|
블록 수행 결과를 반환 | run, with | let |
객체 자신을 반환 | apply | also |
다음은 각 함수의 사용 예입니다.
더보기
fun main(args: Array<String>) {
val person = Person("John Doe", 30)
// `let` 사용
val age = person.let { it.age }
println(age) // 30
// `with` 사용
with(person) {
println(age) // 30
}
// `also` 사용
val result = person.also {
println(it.age) // 30
}
println(result) // Person(name=John Doe, age=30)
// `apply` 사용
val result2 = person.apply {
age = 31
}
println(result2) // Person(name=John Doe, age=31)
// `run` 사용
val result3 = person.run {
age = 32
println(age) // 32
}
println(result3) // 32
}
주의!!
모든 수신객체를 it으로 활용하면 문제가 발생할 수 있어요
더보기
// Scope Function을 중첩으로 사용할 경우 누가 누구의 범위인지 알수 없다!
// Implicit parameter 'it' of enclosing lambda is shadowed 경고 발생!
data class Person(
var name: String = "",
var age: Int? = null,
var child: Person? = null
)
// 잘못된 예시
Person().also {
it.name = "한석봉"
it.age = 40
val child = Person().also {
it.name = "홍길동" // 누구의 it인지 모른다!
it.age = 10 // 누구의 it인지 모른다!
}
it.child = child
}
// 수정한 예시
Person().also {
it.name = "한석봉"
it.age = 40
val child = Person().also { c -> // c를 이용하면 구분을 할 수 있다!!
c.name = "홍길동"
c.age = 10
}
it.child = child
}
'📒 TIL - Today I Learned' 카테고리의 다른 글
20231214 / 비동기 프로그래밍 (0) | 2023.12.14 |
---|---|
20231214 / 확장함수 (0) | 2023.12.14 |
20231213 / 타입확인 / Pair, Triple (0) | 2023.12.13 |
20231212 / 업 캐스팅과 다운 캐스팅 (0) | 2023.12.12 |
20231211 / 키오스크 만들기 (0) | 2023.12.11 |
블로그의 정보
꿈틀꿈틀 개발일기
jeongminy