1) Scope Function ( 범위 지정 함수 )
1-1) 범위 지정 함수
코틀린 표준 라이브러리에서 제공하는 확장 함수
1-2) 목적
간결성, 명료성, 유지보수 용이성 향상
1-3) 정의
객체의 컨텍스트 내에서 실행 가능한 코드 블럭을 만드는 함수
호출 시, 임시 범위가 생성되며, 이 범위 안에서는 이름 없이 객체에 접근 가능
- context : 문맥, 맥락, 전후 사정
1-4) 예
사람이 풍선을 크게 분다.
사람: 객체 풍선: 실행 가능한 코드 블럭
풍선 안에서는 이 사람이 가지고 있는 모든 정보를 사용할 수 있다.
- 사람으로부터 풍선을 생성하거나
- 사람이 함수의 인자로 들어가는 방식, 이렇게 2가지가 있음
2) 수신 객체
2-1) 수신 객체 ( receiver )
확장 함수가 호출되는 대상이 되는 값 (객체)
예) 사람
2-2) 수신 객체 지정 람다 ( lambda with receiver )
수신 객체를 명시하지 않고, 람다의 본문 안에서 해당 객체의 메서드를 호출할 수 있게 하는 것
예) 풍선
2-3) 차이점
수신 객체 접근 방법 : this, it Return 값 : 수신 객체, 마지막 행 ( lambda result )
수신객체 확장함수로 호출 함수의 연산자
this ( 생략가능) | apply | ruin | with |
it ( 생략가능 ) | also | let | - |
return | 수신객체 | 람다 식의 마지막 행 | 람다 식의 마지막 행 |
let : null 체크를 해야할 때, 지역 변수를 명시적으로 표현해야 할 때
run : 객체를 초기화하고 리턴 값이 있을 때
apply : 객체 초기화
also : 수신 객체를 명시적으로 사용하고 싶을 때, 로그를 남길 때
with : 객체 초기화, 람다 리턴 값이 필요 없을 때
3) 실습으로 알아보기
처음 접하니 위 내용이 이해가 안 되었고 강사님의 말이 너무 빨랐다. 실습으로 이해해보자.
3-1) User 클래스 선언
먼저 User 클래스를 선언한다.
class User(
val name : String,
val age : Int,
val gender : Boolean, // true: female, false: male
)
3-2) let
fun main() {
// 확장 함수의 종류
// let, run, apply, also, with
// 1) let
val a = 3
a.let{ }
val user = User("김주연", 10, true)
val age = user.let {
user.age
}
println(age) // 10
}
수신객체.let { user ->
코드 블럭
마지막줄 // return
}
it : 기본값
local variable it을 user → 로 명시할 수 있음
null safe 시 사용함
// 1) let
var user : User? = User("김주연", 10, true)
val age = user?.let {
it.age
}
println(age)
user = null
println(age)
3-3) run
객체를 초기화할 때 많이 사용 함수를 오버라이드할 때
// 2) run
val kid = User("아이", 4, false)
val kid_age = kid.run {
age
// this.age
}
println(kid_age) // 4
val kid_name = kid.run {
name
}
println(kid_name) // com.example.kotlin.User@7c30a502
수신객체.run { this ->
마지막줄 // 리턴값
}
let 과 run 의 차이는 수신 객체를 받는 방식의 차이
it 이냐 this 이냐? this 는 생략가능
3-4) apply
apply 에 대해 설명하기 위해서 클래스에 멤버변수 하나 더 추가
var has_glasses : Boolean
class User(
val name : String,
val age : Int,
val gender : Boolean, // true: female, false: male
var has_glasses : Boolean = true,
)
// 3) apply
val female = User("슬기", 20, true, true)
val female_value = female.apply {
has_glasses = false
}
println(female_value.has_glasses) // false
run 과의 공통점) 수신객체를 this 로 받는다
run 과의 차이점 ) run : 람다 식 리턴 apply : 자기자신 리턴
수신객체.apply {
}
return 값이 수신 객체
3-5) also
// 4) also
val male = User("진현", 17, false, true)
val male_value = male.also { user ->
user.name
user.has_glasses = false
}
println(male_value.has_glasses) // false
수신객체.also { it -> // it 대신 local variable 로 선언 가능
} // return 수신객체 ( 자기자신 )
apply 와 also 의 차이점 apply : this (생략가능) 로 수신 객체를 받음 also : it ( 또는 local variable ) 로 수신 객체를 받음
코틀린 공식 문서에서 추천 apply : 초기화 작업
also : 수신 객체에 대한 내용을 확인하기 위해 로그 찍을 때
val male = User("진현", 17, false, true)
val male_value = male.also {
println(it.name)
}
3-6) with
with 는 확장함수는 아님
// 5) with
// 확장 함수는 아님
val result = with(male) {
has_glasses = false
"값 초기화 성공"
}
println(result) // 값 초기화 성공
함수의 argument(인자) 들어가서 뒤의 코드 블럭에서 사용됨
with(수신객체) { // this
코드블럭
마지막 줄이 리턴값
}
처음부터 적절한 확장함수를 사용하려 하기 보다는 확장 함수 하나씩 사용해보는 것을 추천
4) 전체코드
fun main() {
// 확장 함수의 종류
// let, run, apply, also, with
// 1) let
var user : User? = User("김주연", 10, true)
val age = user?.let {
it.age
}
// 2) run
val kid = User("아이", 4, false)
val kid_age = kid.run {
age
// this.age
}
println(kid_age)
// 3) apply
val female = User("슬기", 20, true, true)
val female_value = female.apply {
has_glasses = false
}
println(female_value.has_glasses) // false
// 4) also
val male = User("진현", 17, false, true)
val male_value = male.also {
println(it.name)
}
// 5) with
// 확장 함수는 아님
val result = with(male) {
has_glasses = false
"값 초기화 성공"
}
println(result) // 값 초기화 성공
}
class User(
val name : String,
val age : Int,
val gender : Boolean, // true: female, false: male
var has_glasses : Boolean = true,
)
'안드로이드 앱(Kotlin|Java) > [2025~] 안드로이드 앱' 카테고리의 다른 글
Part0_Ch02_06 object, companion object (1) | 2025.01.24 |
---|---|
Part0_Ch02_04 초기화 지연 (0) | 2025.01.24 |
Part0_Ch02_02 확장함수 (1) | 2025.01.24 |
Part0_Ch02_01 람다 (0) | 2025.01.24 |
Part0_Ch01_10 String Template (0) | 2025.01.24 |