[Kotlin] 17. 실전 팁 - 자주 쓰는 패턴과 관용구
실무에서 자주 사용하는 Kotlin 패턴과 관용구(idiom)를 정리합니다.
자주 쓰는 패턴
문자열 처리
fun main() {
val text = " Hello, Kotlin World! "
// 공백 제거 + 분리
val words = text.trim().split(" ")
println(words) // [Hello,, Kotlin, World!]
// 빈 문자열 체크
val name = ""
println(name.isEmpty()) // true
println(name.isBlank()) // true (공백만 있어도 true)
println(name.ifEmpty { "기본값" }) // 기본값
println(name.ifBlank { "기본값" }) // 기본값
// 정규식
val email = "user@example.com"
val isValid = email.matches(Regex("[a-zA-Z0-9.]+@[a-zA-Z0-9]+\\.[a-zA-Z]+"))
println(isValid) // true
// 문자열 빌더
val result = buildString {
appendLine("첫 번째 줄")
appendLine("두 번째 줄")
append("마지막 줄")
}
println(result)
}
컬렉션 생성 패턴
fun main() {
// buildList (읽기 전용 리스트를 조건부로 생성)
val items = buildList {
add("필수 항목")
if (true) add("조건부 항목")
addAll(listOf("추가1", "추가2"))
}
// associate (리스트 → 맵 변환)
val users = listOf("홍길동", "김철수", "이영희")
val userMap = users.associateWith { it.length }
println(userMap) // {홍길동=3, 김철수=3, 이영희=3}
// groupBy
val numbers = listOf(1, 2, 3, 4, 5, 6)
val grouped = numbers.groupBy { if (it % 2 == 0) "짝수" else "홀수" }
println(grouped) // {홀수=[1, 3, 5], 짝수=[2, 4, 6]}
// zip (두 리스트 결합)
val names = listOf("홍길동", "김철수")
val ages = listOf(25, 30)
val pairs = names.zip(ages)
println(pairs) // [(홍길동, 25), (김철수, 30)]
}
안전한 타입 변환
fun processInput(input: Any) {
when (input) {
is String -> println("문자열: ${input.uppercase()}")
is Int -> println("정수: ${input * 2}")
is List<*> -> println("리스트: ${input.size}개")
else -> println("알 수 없는 타입")
}
}
// 안전한 캐스팅
fun safeCast(value: Any): String {
return (value as? String) ?: "변환 실패"
}
위임 (Delegation)
// by lazy: 최초 접근 시 초기화
class Config {
val databaseUrl: String by lazy {
println("DB URL 로딩...")
"jdbc:mysql://localhost:3306/mydb"
}
}
// observable: 값 변경 감지
import kotlin.properties.Delegates
class User {
var name: String by Delegates.observable("초기값") { _, old, new ->
println("$old → $new 변경됨")
}
var age: Int by Delegates.vetoable(0) { _, _, new ->
new >= 0 // false 반환 시 변경 거부
}
}
fun main() {
val config = Config()
println(config.databaseUrl) // "DB URL 로딩..." 출력 후 URL 반환
println(config.databaseUrl) // 캐시된 값 반환 (로딩 안 함)
val user = User()
user.name = "홍길동" // 초기값 → 홍길동 변경됨
user.age = -5 // 거부됨 (age는 0 유지)
}
제네릭 활용
// 제네릭 함수
fun <T> List<T>.secondOrNull(): T? {
return if (size >= 2) this[1] else null
}
// 제네릭 클래스
class Result<out T>(
val data: T?,
val error: String?
) {
val isSuccess: Boolean get() = data != null
companion object {
fun <T> success(data: T) = Result(data, null)
fun <T> failure(error: String) = Result<T>(null, error)
}
}
fun main() {
val numbers = listOf(10, 20, 30)
println(numbers.secondOrNull()) // 20
val result = Result.success("데이터")
if (result.isSuccess) {
println(result.data)
}
}
DSL 스타일 빌더
// HTML DSL 예시
class HtmlBuilder {
private val elements = mutableListOf<String>()
fun h1(text: String) { elements.add("<h1>$text</h1>") }
fun p(text: String) { elements.add("<p>$text</p>") }
fun ul(block: UlBuilder.() -> Unit) {
val ul = UlBuilder()
ul.block()
elements.add(ul.build())
}
fun build() = elements.joinToString("\n")
}
class UlBuilder {
private val items = mutableListOf<String>()
fun li(text: String) { items.add("<li>$text</li>") }
fun build() = "<ul>\n${items.joinToString("\n")}\n</ul>"
}
fun html(block: HtmlBuilder.() -> Unit): String {
val builder = HtmlBuilder()
builder.block()
return builder.build()
}
fun main() {
val page = html {
h1("Kotlin DSL")
p("DSL로 HTML을 생성합니다")
ul {
li("항목 1")
li("항목 2")
li("항목 3")
}
}
println(page)
}
유용한 표준 라이브러리 함수
fun main() {
// repeat: N번 반복
repeat(3) { println("반복 $it") }
// takeIf / takeUnless
val number = 42
val even = number.takeIf { it % 2 == 0 } // 42 (조건 만족)
val odd = number.takeUnless { it % 2 == 0 } // null (조건 불만족)
// use: 자동 리소스 해제 (try-with-resources)
java.io.File("test.txt").bufferedReader().use { reader ->
println(reader.readLine())
}
// measureTimeMillis: 실행 시간 측정
val time = kotlin.system.measureTimeMillis {
Thread.sleep(100)
}
println("실행 시간: ${time}ms")
// runCatching: 안전한 실행
val result = runCatching {
"abc".toInt()
}.getOrDefault(0)
println(result) // 0
}
Java → Kotlin 변환 팁
| Java | Kotlin |
|---|---|
new ArrayList<>() |
mutableListOf() |
String.format("%s", x) |
"$x" 또는 "${expr}" |
obj instanceof Type |
obj is Type |
(Type) obj |
obj as Type |
obj != null ? obj.method() : null |
obj?.method() |
Collections.unmodifiableList(list) |
list.toList() |
try { } finally { close() } |
.use { } |
| getter/setter | val / var (자동 생성) |
- [Kotlin] 18. 빌드와 배포 - Gradle, APK, JAR
- [Kotlin] 17. 실전 팁 - 자주 쓰는 패턴과 관용구
- [Kotlin] 16. 테스트 - JUnit, 단위 테스트
- [Kotlin] 15. 서버 개발 - Spring Boot with Kotlin
- [Kotlin] 14. 로컬 저장소 - Room, DataStore
- [Kotlin] 13. 네트워크 통신 - Retrofit
- [Kotlin] 12. 상태관리 - ViewModel, State
- [Kotlin] 11. 화면 이동 - Navigation
- [Kotlin] 10. Compose 레이아웃과 리스트
- [Kotlin] 09. Android 개발 기초 - 프로젝트 생성
- [Kotlin] 08. 코루틴 - 비동기 프로그래밍
- [Kotlin] 07. Null 안전성과 예외 처리
- [Kotlin] 06. 컬렉션 - List, Map, Set
- [Kotlin] 05. 클래스와 객체지향 프로그래밍
- [Kotlin] 04. 함수 - 선언, 매개변수, 람다
- [Kotlin] 03. 제어문 - 조건문, 반복문
- [Kotlin] 02. 변수와 데이터 타입
- [Kotlin] 01. Kotlin 소개 및 개발환경 설치