[코틀린] studay day 5

승아·2020년 10월 14일
0

고차함수 표현법

// 함수를 이용한 람다식
val result = high("Sean", { x -> inc(x+3) })
// 소괄호 바깥으로 빼내고 생략
val result2 = high("Sean") { inc(it + 3) }
// 매개변수 없이 함수의 이름만 사용할 때
val result3 = hgih("Kim", ::inc)
// 람다식 자체를 넘겨 준 형태
val result4 = high("Sean") { x -> x + 3 }
// 매개변수가 한 개인 경우 생략
val result5 = hgih("Sean") { it + 3 }
// 만일 일반 매개변수가 없고 람다식이 유일한 인자라면 다음과 같이 표현 가능
val result6 = hgihNoArg{ it + 3 }

클로저

  • 람다식으로 표현된 내부 함수에서 외부 범위에 선언된 변수에 접근할 수 있는 개념
  • 람다식 안에 있는 외부 변수는 값을 유지하기 위해 람다가 포획(capture)한 변수
var result = 0 //외부의 변수
calc.addNum(2,3) { x,y -> result = x + y } // 클로저
println(result) // 값을 유지하여 5가 출력

let()

  • 함수를 호출하는 객체 T를 이어지는 block의 인자로 넘기고 block의 결과값 R을 반환
public inline fun <T,R> T.let(block: (T) -> R): R {... return block(this) }
score?.let { println("Score: $it") } // let을 사용해 null 검사를 제거
val str = score.let { it.toString() }
println(str)
  • let 함수 체이닝
a = a.let{ it + 2 }.let{ 
	println("a = $a") 
    val i = it + b 
    i
}
println(a) // 출력 : 5
  • let의 중첩 사용
var x = "Kotlin!"
	x.let { outer -> 	
    	outer.let { inner ->
        	// 이때는 it을 사용하지 않고 명시적이름을 사용
        	print("Inner is $inner and outer is $outer")
            }
      }
  • 반환값은 바깥쪽의 람다식에만 적용
var x = "Kotlin!"
	x.let { outer -> 	
    	outer.let { inner ->
        	// 이때는 it을 사용하지 않고 명시적이름을 사용
        	print("Inner is $inner and outer is $outer")
            "Inner String" // 이건 반환되지 않음
          }
          "Outer String" // 이 문자열이 반환되 x에 할당
    }
  • null 검사
var obj: String?
obj?.let { // obj가 null이 아닐 경우 작업 수행
	Toast.makeText(applicationContext, it, Toast.LENGTH_LONG).show()
}
  • else문이 포함된 문장 대체
// ?: 사용
firstName?.let { print("$it $lastName") } ?: print("$lastName")

also()

  • 함수를 호출하는 객체 T를 이어지는 block에 전달하고 객체 T 자체를 반환
public inline fun <T> T.also(block: (T) -> Unit): T { block(this); return this }
val b = person.also {
	it.skills = "Java"
	"success"
}
println(b) // "success"가 아닌 person객체 출력

apply()

  • also()함수와 마찬가지로 호출하는 객체 T를 이어지는 block으로 전달하고 객체 자체인 this를 반환
public inline fun <T> T.apply(block: T.() -> Unit): T { block(); return this }
person.apply { this.skills = "Switf } // this 생략 가능

run()

  • 인자가 없는 익명 함수처럼 동작하는 형태와 객체에서 호출하는 형태 두 가지로 사용
public inline fun <R> run(block: () -> R): R = return block()
public inline fun <T, R> T.run(block: T.() -> R): R = return block()
skiils = run {
	val level = "Kotlin Level: " + a
    level // 마지막 표현식이 반환됨
}

with()

  • 인자로 받는 객체를 이어지는 block의 receiver로 전달하며 결과값을 반환
public inline fun <T, R> with(receiver: T, block: T.() -> R): R = receiver.block()
  • with는 세이프 콜(?.)은 지원하지 않기 때문에 let과 같이 사용
supportActionBar?.let {
	with(it){
    	setDisplayHomeAsUpEnabled(true)
        setHomeAsUpIndicator(R.drawable.ic_clear_white)
   }
}
  • let과 with 표현 병합 == run
supportActionBar?.run{
	setDisplayHomeAsUpEnabled(true)
        setHomeAsUpIndicator(R.drawable.ic_clear_white)
}

takeIf()

  • 람다식이 true이면 객체 T를 반환 그렇지 않은 경우 null 반환
someObject?.takeIf{ it.status}?.apply{ doThis()}

takeUnless()

  • 람다식이 false이면 객체 T를 반환 그렇지 않은 경우 null 반환

use()

  • 객체를 사용한 후 close() 등을 자동적으로 호출해 닫아준다
PrintWriter(FileOutputStream("d::\\test\\output.txt")).use{
	it.println("hello")
}

부스트코스 코틀린강좌를 참고하였습니다.

0개의 댓글