Lined Notebook

[자바 개발자를 위한 코틀린 입문] 다양한 함수 다루기

by dev.hardy

코틀린에서 다양한 함수를 다루는 방법

인프런에서 최태현 지식 공유자님의
자바 개발자를 위한 코틀린 입문을 수강하며 정리한 내용 입니다.
하단에 강의 링크 있습니다.

확장 함수

배경

  • 코틀린은 자바와 100% 호환하는 것을 목표로 함
  • 기존 자바 코드위에 자연스럽게 코틀린 코드를 추가할 수 없을까?
    • 자바로 만들어진 라이브러리를 유지보수, 확장할 때 코틀린 코드를 덧붙이고 싶음

→ 어떤 클래스안에 있는 메소드처럼 호출하지만 함수는 밖에서 만들 수 있게 하자! : 확장 함수

예) 호출한 문자열의 가장 끝 문자를 가져오는 확장함수를 만들어보자

fun String.lastChar(): Char { // (1)
    return this[this.length - 1] // (2)
}

(1) String 클래스를 확장함을 알 수 있다. → String은 수신객체 타입 이라고 부른다.

(2) 함수 안에서는 this를 통해 호출한 인스턴스에 접근 가능하다!

  • 이때 this는 수신객체라고 부른다.
fun 확장할려는클래스.함수이름(파라미터): 리턴타입 {
    // this를 이용해 실제 클래스 안의 값에 접근 가능
}

예) 사용해보기

fun main() {
    val name = "hardy"
    println(name.lastChar()) // (1) 사용
}
/**
y
*/

(1) 원래 String 클래스에 있는 멤버 함수처럼 사용가능

🧱 여기서 확장함수가 public이고 확장함수에서 수신 객체 클래스의 private 함수를 가져오면 캡슐화가 깨지는 것이 아닐까?

→ 그래서 확장함수는 클래스에 있는 private or protected 멤버를 가져올 수 없다.

🧱 멤버함수와 확장함수의 시그니처가 같다면? (함수이름이 같다면)

→ 호출을 하면 멤버함수를 우선적으로 호출된다.

→ 확장함수를 만들었지만, 다른 기능의 똑같은 멤버함수가 생기면? → 오류가 발생할 수 있다.

🧱 확장함수가 오버라이드 된다면?

→ 타입에 따라 호출되는 확장함수가 달라진다.

→ 즉, 해당 변수의 현재 타입 에 따라 정적인 타입에 의해 어떤 확장함수가 호출될지 결정됨

🧱 자바에서는 어떻게 코틀린의 확장함수를 사용할까?

→ 정적 메소드를 부르는 것처럼 사용 가능하다.

확장함수라는 개념은 확장프로퍼티 와도 연결됨

fun String.lastChar(): Char { // 확장함수
    return this[this.length - 1]
}

val String.lastChar: Char // 확장 프로퍼티
    get() = this[this.length - 1]

확장 프로퍼티의 원리는 확장함수 + custom getter와 동일!

infix 함수

중위함수: 함수를 호출하는 새로운 방법!

→ downTo, step 도 함수: 중위 호출 함수

변수 함수이름 argument

예) add함수

fun Int.add(other: Int): Int { // 확장함수
    return this + other
}

infix fun Int.addInfix(other: Int): Int { // 중위 함수
    return this + other
}

fun main() {
    val baseNumber = 10
    println(baseNumber.add(3)) // 13
    println(baseNumber addInfix 5) //15
}

→ Infix는 멤버함수에도 붙일 수 있다!

inline 함수

inline 함수: 함수가 호출되는 대신, 함수를 호출한 지점에 함수 본문을 그대로 복붙하고 싶은 경우!

fun main() {
    val baseNumber = 10
    baseNumber.addInline(5) // (1)
} 

inline fun Int.addInline(other: Int): Int {
    return this + other
}

(1) inline 함수를 호출하는 시점에 함수를 호출하지 않고 저 지점에서 함수 본문을 그대로 복붙한다. 바이트 코드로 확인 가능하다.

🧱 이것을 왜 사용할까?

→ 함수를 파라미터로 전달할 때에 오버헤드를 줄일 수 있다.

  • 함수를 중첩해서 사용하는 경우에는 함수가 또 다른 함수를 부르고 또 다른 함수를 부르면 그 함수에 대해서 call chain에 오버헤드를 초래하므로 이거를 줄이기 위해 inline을 사용함

→ 하지만 inline 함수의 사용은 성능 측정과 함께 신중하게 사용해야 함

지역함수

지역함수: 함수 안에 함수

🧱 언제 사용할까?

  • 함수로 추출하면 좋을 것 같은데, 이 함수를 지금 함수 내에서만 사용하고 싶을 때 사용!
  • 하지만 depth가 깊어지기도 하고, 코드가 깔끔하지가 않아진다.

Reference:
자바 개발자를 위한 코틀린 입문

블로그의 정보

개발자 하디 : 기록저장소

dev.hardy

활동하기