Chef.Yeon
Code Cook
Chef.Yeon
전체 방문자
오늘
어제
  • 분류 전체보기 (230)
    • 게임 개발 (1)
      • Unity (1)
    • Android (27)
      • Kotlin (19)
      • 우아한테크코스 5기 (4)
    • Language (11)
      • 파이썬 (3)
      • Java (7)
    • DB (2)
      • SQL (16)
    • Spring (25)
    • 코딩테스트 (56)
    • Git (1)
    • TIL (85)
    • DevOps (6)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 프리코스
  • Android
  • til
  • 문자열
  • kibana
  • ec2
  • webflux
  • Wil
  • 다이나믹 프로그래밍
  • grafana
  • 안드로이드
  • 우아한테크코스
  • 에라토스테네스의 체
  • java
  • rsocket
  • enum
  • spring
  • 코딩테스트
  • 코틀린
  • Docker
  • SQL
  • 백준
  • 코틀린 인 액션
  • MariaDB
  • 프로그래머스
  • 레포지토리
  • 파이썬
  • 내림차순
  • kotlin
  • elasticsearch

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Chef.Yeon

Code Cook

Android/Kotlin

[Kotlin] 고차 함수, 람다, Scope functions

2022. 9. 18. 03:10

Functions types

1. (parameter) -> return type

파라미터 타입 선언 -> 리턴 타입 선언

(Int) -> Boolean

(input: Int) -> Boolean

(T) -> Boolean

val isEven: (Int) -> Boolean = {
    it % 2 == 8
}

파라미터가 두개 이상일 때는 다음과 같다

(Int, Int) -> Int

파라미터명과 타입을 함께 작성할 수도 있다

(first: Int, second: Int) -> Int 

2. with receiver

- 함수 본문에 receiver 객체 참조 전달

.()는 this를 통해 참조(생략 가능)

Int.() -> Boolean

T.() -> R (마지막 줄 반환)

val isEven: Int.() -> Boolean = {
    this % 2 == 0
}

 

고차 함수 higher-order functions

- 함수를 인자/반환값으로 다룰 수 있는 함수

 

Kotlin 함수는 first class

- 함수를 다른 함수의 인자로 전달 가능

- 다른 함수의 반환값이 될 수 있음

- 함수를 변수에 저장 가능

public inline fun <T> Iterable<T>.all(predicate: (T) -> Boolean):Boolean{
    if(this is Collection && isEmpty()) return true
    for (element in this) if(!predicate(element)) return false
    return true
}
val list = listOf(1,2,3,4,5)
list.all{element -> element % 2 == 0} // 람다식

 

lambda expression

1. 

-함수 타입의 인자를 중괄호로 표현하는 식

- arrow(->) 화살표 이후에 수행할 연산 작성

val sum: (Int, Int) -> Int = {x:Int, y:Int -> x + y}
val sum = {x:Int, y:Int -> x + y}

 

2. trailing lambda

- 파라미터가 여러개 이고 마지막 파라미터가 함수 타입인 경우 trailing lambda 지원

fun <T> MutableList(size: Int, init: (index: Int) -> T): MutableList<T>

val list = MutableList(5){index -> index} // 중괄호 람다식이 두 번째 파라미터

두 번 째 파라미터는 index에 따라 초기화를 어떻게 할 것인지 함수 타입으로 전달

{index -> index} 에서 index로 값을 초기화 했으므로

출력은 [0,1,2,3,4]

3. single parameter

filter(predicate: (T) -> Boolean): List<T>

list.filter{
    it > 0
}

4. 반환값

val sum: (Int, Int) -> Int = {
    first:Int, second:Int -> first+second
}

val result = sum(1,2) // ==3

 

Scope functions

1. let

// 수신객체와 blcok의 파라미터 타입 T가 동일
// :R block의 가장 마지막 줄 반환
inline fun <T, R> T.let(block: (T) -> R): R

// 파라미터의 타입이 Nullable 허용하지 않음
fun processNonNullString(str: String){}

val str: String? = "Hello"

// let을 통해 str이 Null이 아닐때 함수 호출
val length = str?.let{
    println("let() called on $it")
    processNonNullString(it)
    it.length
}

let block 의 it으로 null이 아닌 경우에만 값이 전달

block 내부에서 processNonNullString 함수의 인자로 it 전달

마지막 줄인 it.length 가 반환되어 length 변수에 저장

2. with

- 세이프 콜 연산자와 함께 쓰일 수 없어 null 여부를 확인해야하는 경우 다른 함수를 사용

inline fun <T,R> with(receiver:T, bloeck:T.() -> R): R

val numbers = mutableListOf("One", "two", "three")
with(numbers) {
    println("'with' is called with argument $this") // numbers 요소 순차적으로 출력
    println("It contains $size elements") // numbers 크기 출력
}

3. run

map은 키를 조회했을 때 값이 없을 수 있으므로 반환타입이 Nullable

세이프 콜 연산자를 사용하여 null 여부를 확인

inline fun <T,R> T.run(block:T.() -> R): R

val products = mapOf(
    "패션" to "겨울패딩"
    "전자기기" to "핸드폰"
)
products["패션"]?.let{
    println("상품명: $it")
}
products["패션"]?.run{
    println("상품명: $this")
}

 

4. run (확장 함수 아닌 경우)

- 수신 객체 없이 block 안에서 특정 코드를 수행해야하는 경우 사용

inline fun <R> run(block: () -> R): R

products["패션"]?.run{
    println("상품명: $this")
} ?: run{
    println("패션 카테고리에 등록된 상품이 없습니다.")
}

"패션" 이라는 key로 조회했을 때 값이 없는 경우에 대한 처리를 해야할 때 사용 (엘비스 연산자 사용)

5. apply

// block의 반환 타입 Unit
// 수신 객체의 타입이 반환 타입
inline fun <T> T.apply(block: T.() -> Unit): T

val adam = Person("Adam").apply {
    age = 32
    city = "London"
}

println(adam) // Person(name=adam, age=32, city=London)

객체를 생성하는 시점에 추가로 작업 수행

this 참조를 생략하고 age, city 프로퍼티에 값 할당

블럭 내부에서 할당한 값이 반영됨

6. also

inline fun <T> T.also(block: (T) -> Unit): T

val numbers = mutableListOf("one", "two", "three")
numbers
    .also{println("The list elements before adding new one: $it")} // [one, two, three]
    .add{"four"}

mutableList 객체가 생성된 이후에 추가로 처리해야할 작업 수행

 

728x90

'Android > Kotlin' 카테고리의 다른 글

[코틀린 인 액션] 2장 정리  (0) 2022.11.24
[Kotlin] enum, sealed class  (0) 2022.09.27
[Kotiln] Nested & inner class, Extension함수, Generics  (0) 2022.09.16
[Kotlin] object  (0) 2022.09.16
[Kotlin] List, Set, Map, Collection Operations  (0) 2022.09.16
    'Android/Kotlin' 카테고리의 다른 글
    • [코틀린 인 액션] 2장 정리
    • [Kotlin] enum, sealed class
    • [Kotiln] Nested & inner class, Extension함수, Generics
    • [Kotlin] object
    Chef.Yeon
    Chef.Yeon
    보기 좋고 깔끔한 코드를 요리하기 위해 노력하고 있습니다.

    티스토리툴바