6.2 KiB
6.2 KiB
코틀린의 특수 기능과 주요 키워드
코틀린은 개발 생산성을 높이는 다양한 특수 기능을 제공한다.
이 글에서는 코틀린의 고급 기능을 사용 예시와 함께 설명하겠다. 🚀
✨ 소개할 내용
inline함수reified키워드- 제너릭(Generic)
- 위임(Delegation) 패턴과
by키워드
1. inline 함수: 함수 호출 비용 줄이기
코틀린의 inline 함수는 함수 호출 오버헤드를 줄이기 위해 사용된다.
1.1. 기본적인 inline 함수 예제
inline fun execute(block: () -> Unit) {
println("실행 시작")
block()
println("실행 종료")
}
fun main() {
execute {
println("실제 로직 실행")
}
}
출력 결과:
실행 시작
실제 로직 실행
실행 종료
- 함수 호출이 사라지고 코드가 그대로 복사됨 (인라이닝)
- 람다를 인자로 받을 때 유용
- 단점: 코드 크기가 증가할 수 있음 (작은 함수에만 사용)
2. reified 키워드: 실행 시점에서 타입 유지
코틀린에서는 제너릭 타입 정보가 실행 시점에 사라지는 문제(type erasure)가 있음.
하지만 reified 키워드를 사용하면 실행 시점에서도 타입을 유지할 수 있음.
2.1. reified 없이 제너릭 타입 확인 불가
fun <T> getClassName(): String {
return T::class.simpleName // 오류 발생!
}
fun main() {
println(getClassName<String>())
}
- 오류 발생! 제너릭 타입은 실행 시점에서 사라지기 때문.
2.2. reified 키워드 사용하여 해결
inline fun <reified T> getClassName(): String {
return T::class.simpleName ?: "알 수 없음"
}
fun main() {
println(getClassName<String>()) // "String"
println(getClassName<Int>()) // "Int"
}
reified를 사용하면 실행 시점에서도 제너릭 타입을 알 수 있음- 주의:
inline함수에서만reified사용 가능
3. 제너릭(Generic): 타입을 유연하게 만들기
제너릭을 사용하면 코드의 재사용성을 높이고, 타입 안정성을 유지할 수 있음.
3.1. 기본적인 제너릭 사용
class Box<T>(val value: T) {
fun get(): T = value
}
fun main() {
val intBox = Box(123)
val strBox = Box("Hello")
println(intBox.get()) // 123
println(strBox.get()) // Hello
}
T를 사용하여 어떤 타입이든 저장할 수 있는 클래스를 정의
3.2. 제너릭 함수 사용
fun <T> printItem(item: T) {
println("아이템: $item")
}
fun main() {
printItem(42) // 아이템: 42
printItem("코틀린") // 아이템: 코틀린
}
- 함수에도 제너릭 적용 가능
4. 위임(Delegation) 패턴과 by 키워드
코틀린의 by 키워드는 객체의 기능을 다른 객체에 위임할 때 사용된다.
이를 통해 불필요한 코드 중복을 방지할 수 있다.
4.1. 인터페이스를 이용한 기본 위임 패턴
interface Printer {
fun printMessage()
}
class ConsolePrinter : Printer {
override fun printMessage() {
println("콘솔에 출력")
}
}
class SmartPrinter(private val printer: Printer) : Printer {
override fun printMessage() {
println("스마트 프린터 작동 중...")
printer.printMessage()
}
}
fun main() {
val printer = SmartPrinter(ConsolePrinter())
printer.printMessage()
}
출력 결과:
스마트 프린터 작동 중...
콘솔에 출력
SmartPrinter가ConsolePrinter의 기능을 위임(Delegation)
4.2. by 키워드를 사용한 간결한 위임 패턴
class SmartPrinter2(private val printer: Printer) : Printer by printer
fun main() {
val printer = SmartPrinter2(ConsolePrinter())
printer.printMessage() // "콘솔에 출력"
}
by printer를 사용하면 위임을 자동으로 처리- 코드가 훨씬 간결해짐
5. by lazy를 활용한 지연 초기화
by lazy를 사용하면 객체를 필요할 때만 초기화할 수 있다.
class Example {
val lazyValue: String by lazy {
println("초기화 중...")
"Hello, Kotlin!"
}
}
fun main() {
val example = Example()
println("객체 생성 완료")
println(example.lazyValue) // 여기서 초기화 발생
println(example.lazyValue) // 이미 초기화됨, 출력만 함
}
출력 결과:
객체 생성 완료
초기화 중...
Hello, Kotlin!
Hello, Kotlin!
by lazy는 최초 접근 시점에만 실행됨- 이후에는 이미 생성된 값을 사용
6. object 키워드: 싱글톤 객체
코틀린에서 싱글톤 객체를 만들 때 object 키워드를 사용한다.
object Singleton {
fun showMessage() {
println("싱글톤 객체 실행!")
}
}
fun main() {
Singleton.showMessage()
}
출력 결과:
싱글톤 객체 실행!
- 별도의 인스턴스 생성 없이
Singleton.showMessage()사용 가능- 앱 설정, 네트워크 요청 관리 등에 유용
🔹 정리: 코틀린의 특수 기능 요약
| 기능 | 설명 | 사용 예시 |
|---|---|---|
inline 함수 |
함수 호출을 줄이고 성능 향상 | inline fun execute(block: () -> Unit) {} |
reified |
실행 시점에서도 제너릭 타입 유지 | inline fun <reified T> getType() = T::class.simpleName |
| 제너릭 | 코드의 재사용성과 타입 안정성 유지 | class Box<T>(val value: T) |
| Delegation | 클래스 기능을 다른 객체에 위임 | class PrinterImpl : Printer by ConsolePrinter() |
by lazy |
지연 초기화 | val name: String by lazy { "코틀린" } |
object |
싱글톤 객체 | object Singleton {} |
코틀린의 강력한 기능들을 활용하면 코드를 더 간결하고 효율적으로 작성할 수 있다.
이제 직접 사용해보면서 익숙해지자! 🚀