Language/kotlin

다양한 함수 다루기

kimjingyu 2023. 5. 24. 00:57
728x90

확장함수

  • 기존 자바 코드위에 자연스럽게 코틀린 코드를 추가한다는 개념에서 출발
    • 자바로 만들어진 라이브러리를 유지보수 및 확장할 때, 코틀린 코드를 덧붙인다.
  • 따라서 어떤 클래스안에 있는 메서드처럼 호출할 수 있지만, 함수는 밖에 만들 수 있게 한다.
  • 확장함수는 클래스에 있는 private 또는 protected 멤버를 가지고 올 수 없다.
  • 멤버함수와 확장함수의 시그니처가 같으면, 멤버함수가 우선적으로 호출된다.
    • 즉, 확장함수를 만들었지만, 다른 기능을 하는 똑같은 시그니처의 멤버함수가 생기면 오류가 발생할 수 있다.
fun String.lastChar(): Char {
    return this[this.length - 1]
}
  • fun: 이건 함수라는 의미
  • String. : String 클래스를 확장한다는 의미
  • this: 함수 안에서는 this를 통해 인스턴스에 접근 가능하다. (수신 객체)

이를 일반화하면,

fun 확장하려는 클래스.함수이름(파라미터): 반환타입 {
	body에서는 this를 이용해 실제 클래스 안의 값에 접근
}
  • this: 수신객체
  • 확장하려는 클래스: 수신객체 타입

사용해보면, 원래 String에 있는 멤버함수처럼 사용할 수 있다.

val str: String = "ABC"
println(str.lastChar())

❓ 확장함수가 override 된다면

  • 해당 변수의 현재 타입. 즉, 정적인 타입에 의해 어떤 확장 함수가 호출될지 결정된다.
fun Train.isExpensive(): Boolean {
    println("Train의 확장함수")
    return this.price >= 10000
}

fun Srt.isExpensive(): Boolean {
    println("Srt의 확장함수")
    return this.price >= 10000
}
// 확장함수가 오버라이드 된다면
val train: Train = Train()
train.isExpensive()

val srt1: Train = Srt()
srt1.isExpensive()

val srt2: Srt = Srt()
srt2.isExpensive()
Train의 확장함수
Train의 확장함수
Srt의 확장함수

📋 확장함수 중간 정리

  1. 자바 코드가 있는 상황에서 코틀린 코드로 추가 기능 개발을 하기 위해서 확장 함수와 확장 프로퍼티가 등장했다.
  2. 확장함수는 원본 클래스의 private, protected 멤버 접근이 안된다.
  3. 멤버함수, 확장함수 중 멤버함수에 우선권이 있다.
  4. 확장함수는 현재 타입을 기준으로 호출된다.
  5. Java에서는 static 함수를 쓰는 것처럼 코틀린의 확장 함수를 사용할 수 있다.

❓ 자바에서 코틀린 확장함수를 가져다가 사용할 수 있는가

  • 정적 메서드를 부르는 것처럼 사용이 가능하다.
public static void main(String[] args) {
    // 자바에서 코틀린 확장함수를 가져다가 사용하기
    System.out.println(StringUtilsKt.lastChar("ABC"));
}

🔎 확장 프로퍼티

  • 확장함수 개념은 확장 프로퍼티와도 연결된다.
  • 확장 프로퍼티의 원리는 확장함수 + custom getter 와 동일하다.
val String.lastChar: Char
    get() = this[this.length - 1]
public static void main(String[] args) {
    // 자바에서 코틀린 확장함수를 가져다가 사용하기
    System.out.println(StringUtilsKt.getLastChar("ABC"));
}

infix 함수

  • 중위함수. 함수를 호출하는 새로운 방법이다.
    • downTo, step
    • 변수.함수이름(argument) 대신에 변수 함수이름 argument
  • infix는 멤버함수에도 붙일 수 있다.
// infix 함수 - 중위 함수
fun Int.add1(other: Int): Int {
    return this + other
}

infix fun Int.add2(other: Int): Int {
    return this + other
}
// infix - 중위 함수
println(3 add2 9)

inline 함수

  • 함수가 호출되는 대신에 함수를 호출한 지점에 함수 본문을 그대로 복붙하고 싶은 경우에 사용
  • 장점으로 함수를 파라미터로 전달할 때에 오버헤드를 줄일 수 있다는 점이 있다.
  • 하지만 inline 함수의 사용은 성능 측정과 함께 신중하게 사용되어야 한다.
// inline 함수
fun Int.add3(other: Int): Int {
    return this + other
}
// inline 함수
println(3.add3(4))

지역함수

  • 코틀린에서는 함수 안에 함수를 선언할 수 있고, 이를 지역함수라고 부른다.
  • 함수 추출이 가능한 상황에서 현재 함수에서만 사용하려고 할 때 사용한다.
  • 단점: depth가 깊어지고, 코드가 깔끔하지 않다.
728x90