BackEnd/Kotlin
16강. 코틀린에서 다양한 함수를 다루는 방법
hanseom
2024. 4. 6. 07:25
반응형
- 확장함수
- infix 함수
- inline 함수
- 지역함수
확장함수
확장함수는 Kotlin의 목표인 Java와의 100% 호환을 기반으로 기존 Java로 만들어진 라이브러리를 유지보수, 확장할 때 Kotlin 코드를 덧붙이기 위해 만들어 졌습니다. 클래스 안에 있는 메서드처럼 호출할 수 있지만, 함수는 밖에 만들 수 있습니다.
다음은 String 클래스의 확장함수 lastChar() 코드입니다.
fun main() {
val str = "ABC"
println(str.lastChar()) // 멤버 함수처럼 사용합니다.
}
fun String.lastChar(): Char { // fun 확장하려는클래스.함수이름(파라미터): 리턴타입
return this[this.length - 1] // this를 이용해 실제 클래스 안의 값에 접근
}
확장함수 특징
- 확장함수는 원본 클래스의 private 또는 protected 멤버 접근이 되지 않습니다.
- 확장함수와 멤버함수의 시그니처가 동일하다면 멤버함수가 우선적으로 호출됩니다.
다음은 Java의 멤버 함수와 Kotlin의 확장 함수 코드입니다. 메인 함수에서 nextYearAge()를 호출할 경우, Java의 멤버함수가 호출됩니다.
// [Java] public class Person { private final String firstName; private final String lastName; private int age; public Person(String firstName, String lastName, int age) { this.firstName = firstName; this.lastName = lastName; this.age = age; } public String getFirstName() { return firstName; } public int getAge() { return age; } public int nextYearAge() { System.out.println("멤버 함수"); return this.age + 1; } } // [Kotlin] fun Person.nextYearAge(): Int { println("확장 함수") return this.age + 1 }
- 확장함수가 오버라이드 된 경우, 해당 변수의 현재 타입에 의해 어떤 확장함수가 호출될지 결정됩니다.
open class Train( val name: String = "새마을기차" val price: Int = 5_000, ) fun Train.isExpensive(): Boolean { println("Train의 확장함수") return this.price >= 10000 } class Srt : Train("SRT", 40_000) fun Srt.isExpensive(): Boolean { println("Srt의 확장함수") return this.price >= 10000 } /* val train: Train = Train() train.isExpensive() // Train의 확장함수 val srt1: Train = Srt() srt1.isExpensive() // Train의 확장함수 val srt2: Srt = Srt() srt2.isExpensive() // Srt의 확장함수 */
- Java에서 Kotlin의 확장 함수는 정적 메서드를 부르는 것처럼 사용 가능합니다.
public static void main(String[] args) { StringUtilsKt.lastChar("ABC"); }
- 확장함수 개념은 확장 프로퍼티와도 연결됩니다. 확장 프로퍼티의 원리는 확장함수 + custom getter와 동일합니다.
fun String.lastChar(): Char { return this[this.length - 1] } val String.lastChar: Char get() = this[this.length - 1]
infix 함수
- 중위함수는 새로운 함수 종류가 아닙니다. 함수를 호출하는 새로운 방법입니다.
- 변수.함수이름(argument) 대신 변수 함수이름 argument 로 호출합니다. (downTo, step 등)
fun Int.add(other: Int): Int {
return this + other
}
infix fun Int.add2(other: Int): Int {
return this + other
}
3.add(4)
3.add2(4)
3 add2 4
- infix 키워드는 확장함수 뿐만 아니라 멤버함수에도 붙일 수 있습니다.
inline 함수
함수가 호출되는 대신 함수를 호출한 지점에 함수 본문을 그대로 붙여넣고 싶은 경우 사용합니다. 즉 inline 키워드를 붙이면, 함수를 호출하는 곳에 동일한 코드가 복사/붙여넣기 되는 것입니다. 함수를 파라미터로 전달할 때 오버헤드를 줄일 수 있으나, 성능 측정과 함께 신중하게 사용되어야 합니다.
inline fun Int.add3(other: Int): Int {
return this + other
}
지역함수
함수 안에 함수를 선언할 수 있는 것을 지역함수라고 합니다. 함수 내에서 중복된 코드를 함수로 추출할 때 사용합니다.
fun createPerson(firstName: String, lastName: String): Person {
fun validateName(name: String, fieldName: String) {
if (name.isEmpty()) {
throw IllegalArgumentException("${fieldName}은 비어있을 수 없습니다.")
}
}
validateName(firstName, "firstName")
validateName(lastName, "lastName")
return Person(firstName, lastName, 1)
}
감사합니다.
반응형