개발/Kotlin

[Kotlin In Action] 5. λžŒλ‹€λ‘œ ν”„λ‘œκ·Έλž˜λ°

도리 🐟 2021. 5. 29. 01:15
  • λžŒλ‹€μ‹/λžŒλ‹€: λ‹€λ₯Έ ν•¨μˆ˜μ— λ„˜κΈΈ 수 μžˆλŠ” μž‘μ€ μ½”λ“œ 쑰각

#1. λžŒλ‹€μ‹κ³Ό 멀버 μ°Έμ‘°

λžŒλ‹€: μ½”λ“œ λΈ”λŸ­μ„ ν•¨μˆ˜ 인자둜 λ„˜κΈ°κΈ°

λžŒλ‹€ 식을 μ‚¬μš©ν•˜λ©΄ ν•¨μˆ˜λ₯Ό μ„ μ–Έν•  ν•„μš”κ°€ μ—†κ³ , μ½”λ“œ λΈ”λŸ­μ„ 직접 ν•¨μˆ˜μ˜ 인자둜 전달할 수 μžˆλ‹€.

button.setOnClickListener { /* actions on click */ }

-> λžŒλ‹€λ₯Ό λ©”μ„œλ“œκ°€ ν•˜λ‚˜λΏμΈ 무λͺ… 객체 λŒ€μ‹  μ‚¬μš©ν•  수 μžˆλ‹€.

λžŒλ‹€μ™€ μ»¬λ ‰μ…˜

  • μ˜ˆμ‹œ) maxBy: μ»¬λ ‰μ…˜μ—μ„œ νŠΉμ • 쑰건을 κΈ°μ€€μœΌλ‘œ κ°€μž₯ 큰 μ›μ†Œλ₯Ό μ°Ύμ•„ λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜
val people = listOf(Person("Alice", 29), Person("Bob", 31))
println(people.maxBy { it.age }) //λΉ„κ΅μ˜ 기쀀이 될 값을 λžŒλ‹€λ‘œ μ „λ‹¬ν•œλ‹€.

ν•¨μˆ˜λ‚˜ ν”„λ‘œνΌν‹°λ₯Ό λ°˜ν™˜ν•˜λŠ” 역할을 μˆ˜ν–‰ν•˜λŠ” λžŒλ‹€λŠ” 멀버 참쑰둜 λŒ€μΉ˜ν•  수 μžˆλ‹€.

people.maxBy(Person::age)

λžŒλ‹€ μ‹μ˜ 문법

λžŒλ‹€λŠ” κ°’μ²˜λŸΌ μ—¬κΈ°μ €κΈ° 전달할 수 μžˆλŠ” λ™μž‘μ˜ λͺ¨μŒμ΄λ‹€.
λ³€μˆ˜μ— μ €μž₯ν•  μˆ˜λ„ μžˆλ‹€.
ν•¨μˆ˜μ— 인자둜 λ„˜κΈ°λ©΄μ„œ λ°”λ‘œ λžŒλ‹€λ₯Ό μ •μ˜ν•˜λŠ” κ²½μš°κ°€ λŒ€λΆ€λΆ„μ΄λ‹€.

μ½”ν‹€λ¦°μ—μ„œλŠ” ν•¨μˆ˜ 호좜 μ‹œ 맨 뒀에 μžˆλŠ” μΈμžκ°€ λžŒλ‹€ 식이면 κ·Έ λžŒλ‹€λ₯Ό κ΄„ν˜Έ λ°–μœΌλ‘œ λΉΌλ‚Ό 수 μžˆλ‹€.

λžŒλ‹€κ°€ μ–΄λ–€ ν•¨μˆ˜μ˜ μœ μΌν•œ 인자이고 κ΄„ν˜Έ 뒀에 λžŒλ‹€λ₯Ό 썼닀면, 호좜 μ‹œ 빈 κ΄„ν˜Έλ₯Ό 없애도 λœλ‹€.

people.maxBy { p: Person -> p.age }

 

μΈμžκ°€ μ—¬λŸΏ μžˆλŠ” κ²½μš°μ—λŠ” λžŒλ‹€λ₯Ό λ°–μœΌλ‘œ λΉΌλ‚Ό μˆ˜λ„ μžˆκ³  λžŒλ‹€λ₯Ό κ΄„ν˜Έ μ•ˆμ— μœ μ§€ν•΄μ„œ ν•¨μˆ˜μ˜ μΈμžμž„을 λΆ„λͺ…νžˆ ν•  μˆ˜λ„ μžˆλ‹€. λ‘˜ μ΄μƒμ˜ λžŒλ‹€λ₯Ό μΈμžλ‘œ λ°›λŠ” κ²½μš° κ΄„ν˜Έλ₯Ό μ‚¬μš©ν•˜λŠ” μΌλ°˜μ μΈ ν•¨μˆ˜ ν˜ΈμΆœ κ΅¬λ¬Έμ„ μ‚¬μš©ν•˜λŠ” νŽΈμ΄ λ‚«λ‹€.

 

 

λžŒλ‹€μ˜ νŒŒλΌλ―Έν„°κ°€ ν•˜λ‚˜λΏμ΄κ³  κ·Έ νƒ€μž…μ„ μ»΄νŒŒμΌλŸ¬κ°€ μΆ”λ‘ ν•  수 μžˆλŠ” 경우 it을 λ°”λ‘œ μ“Έ 수 μžˆλ‹€.

people.maxBy { it.age }

 

λžŒλ‹€ μ•ˆμ— λžŒλ‹€κ°€ μ€‘μ²©λ˜λŠ” 경우 각 λžŒλ‹€μ˜ νŒŒλΌλ―Έν„°λ₯Ό λͺ…μ‹œν•˜λŠ” 편이 λ‚«λ‹€.

 

 

λžŒλ‹€λ₯Ό λ³€μˆ˜μ— μ €μž₯ν•  λ•ŒλŠ” νŒŒλΌλ―Έν„° νƒ€μž…μ„ λͺ…μ‹œν•΄μ•Ό ν•œλ‹€.

val getAge = { p: Person -> p.age }

본문이 μ—¬λŸ¬ μ€„λ‘œ 이뀄진 경우 본문의 맨 λ§ˆμ§€λ§‰μ— μžˆλŠ” 값이 λžŒλ‹€μ˜ κ²°κ³Ό 값이 λœλ‹€.

val sum = { x: Int, y: Int ->
    println("Computing the sum of $x and $y...")
    x+y
}

 

ν˜„μž¬ μ˜μ—­μ— μžˆλŠ” λ³€μˆ˜μ— μ ‘κ·Ό

λžŒλ‹€λ₯Ό ν•¨μˆ˜ μ•ˆμ—μ„œ μ •μ˜ν•˜λ©΄ ν•¨μˆ˜μ˜ νŒŒλΌλ―Έν„°λΏ μ•„λ‹ˆλΌ λžŒλ‹€ μ •μ˜μ˜ μ•žμ— μ„ μ–Έλœ 둜컬 λ³€μˆ˜κΉŒμ§€ λžŒλ‹€μ—μ„œ λͺ¨λ‘ μ‚¬μš©ν•  수 μžˆλ‹€.
νŒŒμ΄λ„ λ³€μˆ˜κ°€ μ•„λ‹Œ λ³€μˆ˜μ— μ ‘κ·Όν•  수 있고, λ°”κΉ₯의 λ³€μˆ˜λ₯Ό λ³€κ²½ν•  수 μžˆλ‹€

fun printProblemCounts(responses: Collection<String>) {
    var clientErrors = 0 //λžŒλ‹€μ—μ„œ μ‚¬μš©ν•  λ³€μˆ˜ μ„ μ–Έ
    var serverErrors = 0
    responses.forEach {
        if (it.startsWith("4")) {
            clientErrors++ //λžŒλ‹€ μ•ˆμ—μ„œ λžŒλ‹€ λ°–μ˜ λ³€μˆ˜λ₯Ό λ³€κ²½ν•œλ‹€.
        } else if (it.startsWith("5")) {
            serverErrors++
        }
    }
    println("$clientErrors client errors, $serverErrors server errors")
}

λžŒλ‹€ μ•ˆμ—μ„œ μ‚¬μš©ν•˜λŠ” μ™ΈλΆ€ λ³€μˆ˜λ₯Ό 'λžŒλ‹€κ°€ ν¬νšν•œ λ³€μˆ˜(captured variable)'라고 λΆ€λ₯Έλ‹€.

μ–΄λ–€ ν•¨μˆ˜κ°€ μžμ‹ μ˜ 둜컬 λ³€μˆ˜λ₯Ό ν¬νšν•œ λžŒλ‹€λ₯Ό λ°˜ν™˜ν•˜κ±°λ‚˜ λ‹€λ₯Έ λ³€μˆ˜μ— μ €μž₯ν•œλ‹€λ©΄ 둜컬 λ³€μˆ˜μ˜ 생λͺ…주기와 ν•¨μˆ˜μ˜ 생λͺ…μ£ΌκΈ°κ°€ λ‹¬λΌμ§ˆ 수 μžˆλ‹€.

 

  • νŒŒμ΄λ„ λ³€μˆ˜λ₯Ό ν¬νšν•œ 경우: λžŒλ‹€ μ½”λ“œλ₯Ό λ³€μˆ˜ κ°’κ³Ό ν•¨κ»˜ μ €μž₯
  • νŒŒμ΄λ„μ΄ μ•„λ‹Œ λ³€μˆ˜λ₯Ό ν¬νšν•œ 경우: λ³€μˆ˜λ₯Ό νŠΉλ³„ν•œ 래퍼둜 κ°μ‹Έμ„œ λž˜νΌμ— λŒ€ν•œ μ°Έμ‘°λ₯Ό λžŒλ‹€ μ½”λ“œμ™€ ν•¨κ»˜ μ €μž₯ν•œλ‹€.

 

멀버 μ°Έμ‘°

μ½”ν‹€λ¦°μ—μ„œλŠ” μžλ°” 8κ³Ό λ§ˆμ°¬κ°€μ§€λ‘œ ν•¨μˆ˜λ₯Ό κ°’μœΌλ‘œ λ°”κΏ€ 수 μžˆλ‹€.

val getAge = Person::age

::을 μ‚¬μš©ν•˜λŠ” 식을 멀버 참쑰라고 λΆ€λ₯Έλ‹€.
ν”„λ‘œνΌν‹°λ‚˜ λ©”μ„œλ“œλ₯Ό 단 ν•˜λ‚˜λ§Œ ν˜ΈμΆœν•˜λŠ” ν•¨μˆ˜ 값을 λ§Œλ“€μ–΄μ€€λ‹€.
κ·Έ 멀버λ₯Ό ν˜ΈμΆœν•˜λŠ” λžŒλ‹€μ™€ 같은 νƒ€μž…μ΄λ‹€.
μ΅œμƒμœ„μ— μ„ μ–Έλœ ν•¨μˆ˜λ‚˜ ν”„λ‘œνΌν‹°λ₯Ό μ°Έμ‘°ν•  μˆ˜λ„ μžˆλ‹€.

#2. μ»¬λ ‰μ…˜ ν•¨μˆ˜ν˜• API

filter와 map

  • filter: μ»¬λ ‰μ…˜μ„ μ΄ν„°λ ˆμ΄μ…˜ν•˜λ©΄μ„œ 주어진 λžŒλ‹€μ— 각 μ›μ†Œλ₯Ό λ„˜κ²¨ λžŒλ‹€κ°€ trueλ₯Ό λ°˜ν™˜ν•˜λŠ” μ›μ†Œλ§Œ λͺ¨μ€λ‹€. ('μƒˆλ‘œμš΄ μ»¬λ ‰μ…˜'을 λ°˜ν™˜ν•œλ‹€.)

  • map: 주어진 λžŒλ‹€λ₯Ό μ»¬λ ‰μ…˜μ˜ 각 μ›μ†Œμ— μ μš©ν•œ κ²°κ³Όλ₯Ό λͺ¨μ•„μ„œ 'μƒˆ μ»¬λ ‰μ…˜'을 λ§Œλ“ λ‹€.

이런 ν•¨μˆ˜ ν˜ΈμΆœμ€ μ—°μ‡„μ‹œν‚¬ 수 μžˆλ‹€.

 

🌟🌟
κΌ­ ν•„μš”ν•˜μ§€ μ•Šμ€ 경우 ꡳ이 계산을 λ°˜λ³΅ν•˜μ§€ 말라!
λžŒλ‹€λ₯Ό 인자둜 λ°›λŠ” ν•¨μˆ˜μ— λžŒλ‹€λ₯Ό λ„˜κΈ°λ©΄ λ‹¨μˆœν•΄ λ³΄μ΄μ§€λ§Œ λ‚΄λΆ€ 둜직의 λ³΅μž‘λ„λ‘œ 인해 μ‹€μ œλ‘œλŠ” λΉ„νš¨μœ¨μ μΈ 계산식이 될 μˆ˜λ„ μžˆλ‹€.
'λͺ…ν™•νžˆ' μ΄ν•΄ν•˜κ³  μ‚¬μš©ν•΄μ•Ό ν•œλ‹€.

all, any, count, find

  • all: λͺ¨λ“  μ›μ†Œκ°€ μ–΄λ–€ 쑰건을 λ§Œμ‘±ν•˜λŠ”μ§€ νŒλ‹¨
  • any: μ–΄λ–€ 쑰건을 λ§Œμ‘±ν•˜λŠ” μ›μ†Œκ°€ μžˆλŠ”μ§€ νŒλ‹¨
  • count: 쑰건을 λ§Œμ‘±ν•˜λŠ” μ›μ†Œμ˜ 개수 λ°˜ν™˜
  • find: 쑰건을 λ§Œμ‘±ν•˜λŠ” '첫 번째' μ›μ†Œ λ°˜ν™˜ (firstOrNullκ³Ό κ°™λ‹€)

 

μ–΄λ–€ 쑰건에 λŒ€ν•΄ !all을 μˆ˜ν–‰ν•œ 결과와 κ·Έ 쑰건의 뢀정에 λŒ€ν•΄ anyλ₯Ό μˆ˜ν–‰ν•œ κ²°κ³ΌλŠ” κ°™λ‹€. (-> λ“œ λͺ¨λ₯΄κ°•μ˜ 법칙)
가독성을 μœ„ν•΄ any와 all μ•žμ— !λ₯Ό 뢙이지 μ•ŠλŠ” 것이 λ‚«λ‹€.

* ν•¨μˆ˜λ₯Ό μ μž¬μ μ†Œμ— μ‚¬μš©ν•˜κΈ°: count와 size

>> people.filter(canBeInClub27).size

μ΄λ ‡κ²Œ ν•˜λ©΄ filter의 결과둜 쀑간 μ»¬λ ‰μ…˜μ΄ 생긴닀.
countλ₯Ό μ‚¬μš©ν•˜λ©΄ μ›μ†Œμ˜ 개수만 μΆ”μ ν•˜κ³ , 쑰건을 λ§Œμ‘±ν•˜λŠ” μ›μ†Œλ₯Ό λ”°λ‘œ μ €μž₯ν•˜μ§€ μ•Šμ•„μ„œ 이 κ²½μš°μ—λŠ” countκ°€ 더 νš¨μœ¨μ μ΄λ‹€.

groupBy: 리슀트λ₯Ό μ—¬λŸ¬ 그룹으둜 이뀄진 맡으둜 λ³€κ²½

각 그룹은 λ¦¬μŠ€νŠΈμ΄λ‹€. μ˜ˆμ‹œμ—μ„œμ˜ groupBy의 κ²°κ³Ό νƒ€μž…μ€ Map<Int, List>이닀.

flatMapκ³Ό flatten: μ€‘μ²©λœ μ»¬λ ‰μ…˜ μ•ˆμ˜ μ›μ†Œ 처리

  • flatMap: 주어진 λžŒλ‹€λ₯Ό μ»¬λ ‰μ…˜μ˜ λͺ¨λ“  객체에 μ μš©(map)ν•˜κ³ , μ μš©ν•œ κ²°κ³Ό μ–»μ–΄μ§€λŠ” μ—¬λŸ¬ 리슀트λ₯Ό ν•œ λ¦¬μŠ€νŠΈμ— λͺ¨μ€λ‹€(flatten).

  • flatten: νŠΉλ³„νžˆ λ³€ν™˜ν•  λ‚΄μš©μ—†μ΄ 펼치기만 ν•  λ•Œ μ‚¬μš©
    • list.flatten()

 

#3. 지연 계산(lazy) μ»¬λ ‰μ…˜ μ—°μ‚°

people.map(Person::name).filter { it.startsWith("A") }

-> mapμ΄λ‚˜ filter와 같은 μ»¬λ ‰μ…˜ ν•¨μˆ˜λŠ” κ²°κ³Ό μ»¬λ ‰μ…˜μ„ μ¦‰μ‹œ μƒμ„±ν•œλ‹€.

people.asSequence() //μ»¬λ ‰μ…˜μ„ μ‹œν€€μŠ€λ‘œ λ³€ν™˜ν•œλ‹€.
    .map(Person::name) //μ‹œν€€μŠ€λ„ μ»¬λ ‰μ…˜κ³Ό λ˜‘κ°™μ€ APIλ₯Ό μ œκ³΅ν•œλ‹€.
    .filter { it.startsWith("A") }
    .toList() //κ²°κ³Ό μ‹œν€€μŠ€λ₯Ό λ‹€μ‹œ 리슀트둜 λ³€ν™˜ν•œλ‹€.

μ‹œν€€μŠ€λ₯Ό μ‚¬μš©ν•˜λ©΄ 쀑간 μž„μ‹œ μ»¬λ ‰μ…˜μ„ μ‚¬μš©ν•˜μ§€ μ•Šκ³ λ„ μ»¬λ ‰μ…˜ 연산을 연쇄할 수 μžˆλ‹€.

 

지연 계산 μ‹œν€€μŠ€λŠ” Sequence μΈν„°νŽ˜μ΄μŠ€μ—μ„œ μ‹œμž‘ν•œλ‹€.
μ‹œν€€μŠ€λŠ” ν•œ λ²ˆμ— ν•˜λ‚˜μ”© 열거될 수 μžˆλŠ” μ›μ†Œμ˜ μ‹œν€€μŠ€λ₯Ό ν‘œν˜„ν•œλ‹€.
Sequenceμ—μ„œ μ œκ³΅ν•˜λŠ” iterator λ©”μ„œλ“œλ₯Ό 톡해 μ‹œν€€μŠ€λ‘œλΆ€ν„° μ›μ†Œλ₯Ό 얻을 수 μžˆλ‹€.

 

μ‹œν€€μŠ€λŠ” 지연 계산을 ν•˜κΈ° λ•Œλ¬Έμ— μ΅œμ’… μ‹œν€€μŠ€μ˜ μ›μ†Œλ₯Ό ν•˜λ‚˜μ”© μ΄ν„°λ ˆμ΄μ…˜ν•˜κ±°λ‚˜ μ΅œμ’… μ‹œν€€μŠ€λ₯Ό 리슀트둜 λ³€ν™˜ν•΄μ•Ό ν•œλ‹€.

 

큰 μ»¬λ ‰μ…˜μ— λŒ€ν•΄μ„œ 연산을 μ—°μ‡„μ‹œν‚¬ λ•ŒλŠ” μ‹œν€€μŠ€λ₯Ό μ‚¬μš©ν•˜λŠ” 것이 μ’‹λ‹€.
**μ‹œν€€μŠ€κ°€ μ„±λŠ₯이 더 쒋은 κ²½μš°λŠ” 큰 μ»¬λ ‰μ…˜μΈ κ²½μš°λΏμ΄λ‹€. (8μž₯μ—μ„œ μžμ„Ένžˆ 닀룬닀.)

 

μ‹œν€€μŠ€ μ—°μ‚°: 쀑간 μ—°μ‚°κ³Ό μ΅œμ’… μ—°μ‚°

  • 쀑간 μ—°μ‚°: λ‹€λ₯Έ μ‹œν€€μŠ€λ₯Ό λ°˜ν™˜, 항상 지연 κ³„μ‚°λœλ‹€.
  • μ΅œμ’… μ—°μ‚°: κ²°κ³Όλ₯Ό λ°˜ν™˜ (μ»¬λ ‰μ…˜, μ›μ†Œ, 숫자 λ˜λŠ” 객체)

μ΅œμ’… 연산이 없이 μ‹€ν–‰ν•˜λ©΄ μ‹œν€€μŠ€ 연산을 ν•˜μ§€ μ•ŠλŠ”λ‹€.

μ‹œν€€μŠ€μ— λŒ€ν•œ 연산은 각 μ›μ†Œμ— λŒ€ν•΄ 순차적으둜 μ μš©λœλ‹€.
μ›μ†Œμ— 연산을 μ°¨λ‘€λŒ€λ‘œ μ μš©ν•˜λ‹€κ°€ κ²°κ³Όκ°€ 얻어지면 κ·Έ μ΄ν›„μ˜ μ›μ†Œμ— λŒ€ν•΄μ„œλŠ” λ³€ν™˜μ΄ 이뀄지지 μ•Šμ„ μˆ˜λ„ μžˆλ‹€.

μ»¬λ ‰μ…˜μ— λŒ€ν•΄ μˆ˜ν–‰ν•˜λŠ” μ—°μ‚°μ˜ μˆœμ„œλ„ μ„±λŠ₯에 영ν–₯을 λΌμΉœλ‹€.

μ‹œν€€μŠ€ λ§Œλ“€κΈ°

generateSequence()
: μ΄μ „μ˜ μ›μ†Œλ₯Ό 인자둜 λ°›μ•„ λ‹€μŒ μ›μ†Œλ₯Ό κ³„μ‚°ν•œλ‹€.

val naturalNumbers = generateSequence(0) { it + 1 }
val numbersTo100 = naturalNumbers.takeWhile { it <= 100 }
println(numbersTo100.sum()) //sum의 κ²°κ³Όλ₯Ό 계산할 λ•Œ λͺ¨λ“  지연 연산이 μˆ˜ν–‰λœλ‹€.

 

728x90

 

#4. μžλ°” ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€ ν™œμš©

ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€ / SAM(Single Abstract Method) μΈν„°νŽ˜μ΄μŠ€
: 좔상 λ©”μ„œλ“œκ°€ 단 ν•˜λ‚˜λ§Œ μžˆλŠ” μΈν„°νŽ˜μ΄μŠ€

μ½”ν‹€λ¦°μ—μ„œ ν•¨μˆ˜λ₯Ό 인자둜 받을 ν•„μš”κ°€ μžˆλŠ” ν•¨μˆ˜λŠ” ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€κ°€ μ•„λ‹ˆλΌ ν•¨μˆ˜νƒ€μž…μ„ 인자 νƒ€μž…μœΌλ‘œ μ‚¬μš©ν•΄μ•Ό ν•œλ‹€.

 

μžλ°” λ©”μ„œλ“œμ— λžŒλ‹€λ₯Ό 인자둜 전달

ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€λ₯Ό 인자둜 μ›ν•˜λŠ” μžλ°” λ©”μ„œλ“œμ— μ½”ν‹€λ¦° λžŒλ‹€λ₯Ό 전달할 수 μžˆλ‹€.

postponeComputation(1000) { println(42) }

μ»΄νŒŒμΌλŸ¬λŠ” μžλ™μœΌλ‘œ 무λͺ… ν΄λž˜μŠ€μ™€ μΈμŠ€ν„΄μŠ€λ₯Ό λ§Œλ“€μ–΄μ€€λ‹€.

  • λžŒλ‹€μ™€ 무λͺ… 객체의 차이
    • 객체: λͺ…μ‹œμ μœΌλ‘œ μ„ μ–Έν•˜λŠ” 경우, λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•  λ•Œλ§ˆλ‹€ μƒˆλ‘œμš΄ 객체가 μƒμ„±λœλ‹€.
    • λžŒλ‹€: λžŒλ‹€μ— λŒ€μ‘ν•˜λŠ” 무λͺ… 객체λ₯Ό λ©”μ„œλ“œ 호좜 μ‹œλ§ˆλ‹€ 반볡 μ‚¬μš©ν•œλ‹€.

 

λžŒλ‹€κ°€ μ£Όλ³€ μ˜μ—­μ˜ λ³€μˆ˜λ₯Ό ν¬νšν•œλ‹€λ©΄ μ»΄νŒŒμΌλŸ¬λŠ” 맀번 μ£Όλ³€ μ˜μ—­μ˜ λ³€μˆ˜λ₯Ό ν¬νšν•œ μƒˆλ‘œμš΄ μΈμŠ€ν„΄μŠ€λ₯Ό 생성해쀀닀.

*μ½”ν‹€λ¦° inline으둜 ν‘œμ‹œλœ μ½”ν‹€λ¦° ν•¨μˆ˜μ—κ²Œ λžŒλ‹€λ₯Ό λ„˜κΈ°λ©΄ μ•„λ¬΄λŸ° 무λͺ… ν΄λž˜μŠ€λ„ λ§Œλ“€μ–΄μ§€μ§€ μ•ŠλŠ”λ‹€. (8μž₯에 μžμ„Ένžˆ λ‚˜μ˜¨λ‹€.)

 

SAM μƒμ„±μž: λžŒλ‹€λ₯Ό ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€λ‘œ λͺ…μ‹œμ μœΌλ‘œ λ³€κ²½

SAM μƒμ„±μž
: λžŒλ‹€λ₯Ό ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€μ˜ μΈμŠ€ν„΄μŠ€λ‘œ λ³€ν™˜ν•  수 있게 μ»΄νŒŒμΌλŸ¬κ°€ μžλ™μœΌλ‘œ μƒμ„±ν•œ ν•¨μˆ˜

  μ»΄νŒŒμΌλŸ¬κ°€ λžŒλ‹€λ₯Ό ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€ 무λͺ… 클래슀둜 바꾸지 λͺ»ν•˜λŠ” 경우 SAM μƒμ„±μžλ₯Ό μ‚¬μš©ν•  수 μžˆλ‹€.
  λžŒλ‹€λ‘œ μƒμ„±ν•œ ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€ μΈμŠ€ν„΄μŠ€λ₯Ό λ³€μˆ˜μ— μ €μž₯ν•΄μ•Ό ν•˜λŠ” κ²½μš°μ—λ„ SAM μƒμ„±μžλ₯Ό μ‚¬μš©ν•  수 μžˆλ‹€

 

val listener = OnClickListener { view ->
    val text = when (view.id) {
        R.id.button1 -> "First button"
        R.id.button2 -> "Second button"
        else -> "Unknown button"
    }
    toast(text)
}
컴파일러 μž…μž₯μ—μ„œ λžŒλ‹€λŠ” μ½”λ“œ λΈ”λŸ­μΌ 뿐이고, 객체가 μ•„λ‹ˆλ―€λ‘œ 객체처럼 λžŒλ‹€λ₯Ό μ°Έμ‘°ν•  μˆ˜λŠ” μ—†λ‹€.
λžŒλ‹€ μ•ˆμ—μ„œ thisλŠ” κ·Έ λžŒλ‹€λ₯Ό λ‘˜λŸ¬μ‹Ό 클래슀의 μΈμŠ€ν„΄μŠ€λ₯Ό 가리킨닀.

무λͺ… 객체 μ•ˆμ—μ„œλŠ” thisκ°€ κ·Έ 무λͺ… 객체 μΈμŠ€ν„΄μŠ€ μžμ‹ μ„ 가리킨닀.

#5. μˆ˜μ‹  객체 지정 λžŒλ‹€: with와 apply

μˆ˜μ‹  객체 지정 λžŒλ‹€
: μˆ˜μ‹  객체λ₯Ό λͺ…μ‹œν•˜μ§€ μ•Šκ³  λžŒλ‹€μ˜ λ³Έλ¬Έ μ•ˆμ—μ„œ λ‹€λ₯Έ 객체의 λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•  수 있게 ν•˜λŠ” λžŒλ‹€

with ν•¨μˆ˜

withκ°€ λ°˜ν™˜ν•˜λŠ” 값은 λžŒλ‹€ μ½”λ“œλ₯Ό μ‹€ν–‰ν•œ 결과이닀.

fun alphabet(): String {
    val stringBuilder = StringBuilder()
    return with(stringBuilder) { //λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜λ €λŠ” μˆ˜μ‹  객체λ₯Ό μ§€μ •ν•œλ‹€.
        for (letter in 'A'..'Z') {
            this.append(letter) //thisλ₯Ό λͺ…μ‹œν•˜μ—¬ μˆ˜μ‹  객체의 λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œλ‹€.
        }
        append("\nNow I know the alphabet!") //thisλŠ” μƒλž΅ κ°€λŠ₯ν•˜λ‹€.
        this.toString()
    }
}

with ν•¨μˆ˜λŠ” 첫 번째 인자둜 받은 객체λ₯Ό 두 번째 인자둜 받은 λžŒλ‹€μ˜ μˆ˜μ‹  객체둜 λ§Œλ“ λ‹€.

fun alphabet() = with(StringBuilder()) {
    for (letter in 'A'..'Z') {
        append(letter)
    }
    append("\nNow I know the alphabet!")
    toString() 
}

λΆˆν•„μš”ν•œ stringBuilder λ³€μˆ˜λ₯Ό μ—†μ• λ©΄ alphabet() ν•¨μˆ˜κ°€ μ‹μ˜ κ²°κ³Όλ₯Ό λ°”λ‘œ λ°˜ν™˜ν•˜κ²Œ λœλ‹€.

apply ν•¨μˆ˜

applyλŠ” 항상 μˆ˜μ‹  객체λ₯Ό λ°˜ν™˜ν•œλ‹€.
apply의 μˆ˜μ‹  객체가 전달받은 λžŒλ‹€μ˜ μˆ˜μ‹  객체가 λœλ‹€.

객체의 μΈμŠ€ν„΄μŠ€λ₯Ό λ§Œλ“€λ©΄μ„œ μ¦‰μ‹œ ν”„λ‘œνΌν‹° 쀑 일뢀λ₯Ό μ΄ˆκΈ°ν™”ν•΄μ•Ό ν•˜λŠ” 경우 μœ μš©ν•˜λ‹€.

fun createViewWithCustomAttributes(context: Context) =
    TextView(context).apply {
        text = "Sample Text"
        textSize = 20.0
        setPadding(10, 0, 0, 0)
    }