[요약] 클래스 활용, 함수 타입, Scope 함수

pge87132·2023년 9월 25일

Kotlin 문법

목록 보기
4/4
post-thumbnail

클래스 활용

  1. data class
  • equals()
    • data class 객체의 실제 값을 비교한다
    • 일반 클래스에서 == 연산자를 사용해 동등성을 비교할 경우 주소 값을 비교한다
  • hashCode()
  • toString()
    • 실제 값을 출력한다
    • 일반 클래스에서 toString() 을 사용하면 클래스 이름과 hashCode가 출력된다
  1. object
  • 프로그램이 실행되면 인스턴스가 자동으로 생성된다
  • 생성자를 만들 수 없다
  • object expression
    • 무명 객체
    • 클래스/인터페이스 상속
interface ClickListener {
	fun onClick()
}
            
fun main() {
	val clickListener = object : ClickListener {
    	override fun onClick() {
            
        }
    }
}
  1. companion object
  • companion object의 멤버는 클래스 이름을 사용해 호출 가능하다
  • 기본 이름은 Companion 이다
  • 이름을 바꾸는 것이 가능하다
  1. Nested class / inner class
  • 중첩된 클래스
  • 중첩된 인터페이스
  1. this expressions
  • 클래스 멤버가 this를 사용하면 this는 해당 클래스 객체를 가리킨다
  • outer scope가 여러개인 경우 this는 가장 가까운 scope를 가리키고 특정 scope를 지정하려면 this@label 을 활용해야 한다
  1. enum class
  • when
    • else 없이도 모든 조건을 평가한다
enum class Color {
	RED,
    GREEN,
    BLUE
}
val colorCode = when (color) {
    Color.RED -> "#FF0000",
    Color.GREEN -> "#00FF00"
    Color.BLUE -> "#0000FF"
}
  • 생성자, 프로퍼티 선언이 가능하다
enum class Color(val rgb: Int) {
	RED(0xFF0000),
    GREEN(0x00FF00),
    BLUE(0x0000FF)
}
  • 함수 선언이 가능하다
enum class ProtocolState {
	WAITING {
    	override fun signal() = TALKING
    },
    TALKING {
        override fun signal() = WAITING
    }
    abstract fun signal(): ProtocalState
}
  1. sealed class
  • 클래스 간 계층 정의
  • 같은 패키지 내에서만 subclass 선언

동등성 비교

  • Structural equality ==, !=
    • 값을 비교한다
    • equals와 동일하다
  • Referential equality ===, !==
    • 주소값을 비교한다

함수 타입

  1. (parameter) → return type
val isEven: (Int) -> Boolean = {
	it % 2 == 0
}
  1. [with receiver] (receiver type).(parameter) → return type
val isOdd: Int.() -> Boolean = {
	this % 2 != 0
}
val repeatText: String.(Int) -> String = {
    this.repeat(it)
}
val repeatText: String.(times: Int) -> String = { times ->
    this.repeat(times)
}
  • 함수를 호출할 때와 동일하게 호출한다
println(isEven(5))
println(isOdd(5))
println(repeatText("a", 3))
  • 수신 객체와 함수의 parameter를 함께 정의한 경우 수신 객체의 확장 함수로 활용 가능하다
println(5.isOdd())
println("a".repeatText(3))
  1. lambda expression
  • 함수의 마지막 파라미터가 함수인 경우 람다식을 인자로 전달할 수 있다
fun <T> Iterable<T>.filter(
	predicate: (T) -> Boolean
): List<T>
val numbers = listOf(1, 2, 3, 4, 5)
val evenNumbers = numbers.filter {
	it % 2 == 0
}
  1. 고차함수
  • 함수를 인자 / 반환값으로 다룰 수 있는 함수
  • 예시
fun <T, R> Collection<T>.fold(
	initial: R,
    combine: (acc: R, nextElement: T) -> R
) : R {
    var accumulator: R = initial
    for (element: T in this) {
    	accumulator = combine(accumulator, element)
    }
    return accumulator
}
  • Kotlin 함수는 first class 이다
    • 함수를 다른 함수의 인자로 전달 가능하고
    • 다른 함수의 반환값이 될 수 있고
    • 함수를 변수에 저장하는 것이 가능하다

Scope 함수

  • let
    • 확장함수이다
    • 수신 객체를 it으로 참조할 수 있다
    • let의 반환 타입은 람다 본문의 마지막 값으로 결정된다
    • safe call
      • ?. 와 함께 사용하면, 람다의 인자로 null이 아닌 값을 받을 수 있다
  • run
    • 확장함수이다
    • 수신 객체를 this로 참조할 수 있다
    • run의 반환 타입은 람다 본문의 마지막 값으로 결정된다
    • 객체를 초기화하고 값을 리턴하는데 사용된다
    • safe call 사용 가능하다
  • with
    • 확장함수가 아니다
    • 수신 객체를 this로 참조할 수 있다
    • with의 반환 타입은 람다 본문의 마지막 값으로 결정된다
  • apply
    • 확장함수이다
    • 수신 객체를 this로 참조할 수 있다
    • 수신 객체를 반환한다
    • safe call 사용 가능하다
  • also
    • 확장함수이다
    • 수신 객체를 it으로 참조할 수 있다
    • 수신 객체를 반환한다
    • safe call 사용 가능하다
  • 수신 객체가 없는 run
    • 확장함수가 아니다
    • block 은 여러 코드를 실행할 수 있는 람다로 활용된다
    • run의 반환 타입은 람다 본문의 마지막 값으로 결정된다
var user: User? = null
val welcomeMessage = run {
	if (user == null) {
   		"앱을 사용하려면 로그인을 해주세요"
    } else {
        "${user.name} 님, 환영합니다!"
    }
}
  • inline 함수
    • Scope 함수는 모두 inline 함수 + 고차함수 이다.
inline fun <T, R> T.let(block: (T) -> R): R
inline fun <T, R> T.run(block: T.() -> R): R
inline fun <R> run(block: () -> R): R
inline fun <T, R> with(receiver: T, block: T.() -> R): R
inline fun <T> T.apply(block: T.() -> Unit): T
inline fun <T> T.also(block: (T) -> Unit): T
profile
처음 읽는 누구나 이해할 수 있도록 쓰자

0개의 댓글