코틀린 전체 문법 정리

# 코틀린 전체 문법 정리 ## 1. 기본 구조 ### Hello World ```kotlin fun main() { println("Hello, World!") } // 또는 매개변수가 있는 main fun main(args: Array<String>) { println("Hello, ${args.firstOrNull() ?: "World"}!") } ``` ### 패키지와 임포트 ```kotlin package com.example.myapp import kotlin.math.* import java.util.Date as JavaDate import com.example.utils.* // 모든 것 임포트 ``` ## 2. 변수와 상수 ### val vs var ```kotlin val name = "홍길동" // 불변(읽기 전용) - Java의 final var age = 25 // 가변 val PI: Double = 3.14 // 타입 명시 var count: Int // 선언만 (나중에 초기화) count = 10 ``` ### 늦은 초기화 ```kotlin lateinit var userName: String // 나중에 초기화 (var만 가능) val lazyValue: String by lazy { // 처음 사용할 때 초기화 "Heavy computation result" } ``` ## 3. 데이터 타입 ### 기본 타입 ```kotlin // 정수 val byte: Byte = 127 val short: Short = 32767 val int: Int = 2147483647 val long: Long = 9223372036854775807L // 실수 val float: Float = 3.14f val double: Double = 3.14159 // 문자와 문자열 val char: Char = 'A' val string: String = "Hello" // 불린 val boolean: Boolean = true // 배열 val array = arrayOf(1, 2, 3) val intArray = intArrayOf(1, 2, 3) ``` ### 타입 변환 ```kotlin val i: Int = 100 val l: Long = i.toLong() val d: Double = i.toDouble() val s: String = i.toString() // 안전한 캐스팅 val obj: Any = "Hello" val str: String? = obj as? String // 실패하면 null ``` ## 4. 문자열 ### 문자열 템플릿 ```kotlin val name = "홍길동" val age = 25 println("이름: $name") // 간단한 변수 println("내년 나이: ${age + 1}") // 표현식 println("이름 길이: ${name.length}") // 프로퍼티 접근 ``` ### 원시 문자열 ```kotlin val multiLine = """ 첫 번째 줄 두 번째 줄 세 번째 줄 """.trimIndent() val regex = """\\d{3}-\\d{4}-\\d{4}""" // 이스케이프 불필요 ``` ## 5. 함수 ### 기본 함수 ```kotlin fun add(a: Int, b: Int): Int { return a + b } // 단일 표현식 함수 fun multiply(a: Int, b: Int) = a * b // 매개변수 기본값 fun greet(name: String = "World") = "Hello, $name!" // 명명된 인수 greet(name = "Kotlin") ``` ### 다양한 매개변수 ```kotlin // 가변 인수 fun sum(vararg numbers: Int): Int { return numbers.sum() } sum(1, 2, 3, 4, 5) // 확장 연산자 val array = intArrayOf(1, 2, 3) sum(*array) // 배열을 개별 인수로 전달 ``` ### 고차 함수 ```kotlin fun calculate(x: Int, y: Int, operation: (Int, Int) -> Int): Int { return operation(x, y) } val result = calculate(5, 3) { a, b -> a + b } // 람다 // 함수 타입 변수 val operation: (Int, Int) -> Int = { a, b -> a * b } ``` ### 확장 함수 ```kotlin // String에 확장 함수 추가 fun String.isPalindrome(): Boolean { return this == this.reversed() } "level".isPalindrome() // true // 제네릭 확장 함수 fun <T> List<T>.secondOrNull(): T? { return if (size >= 2) this[1] else null } ``` ### 인라인 함수 ```kotlin inline fun <T> measure(action: () -> T): T { val start = System.currentTimeMillis() val result = action() println("Execution time: ${System.currentTimeMillis() - start}ms") return result } ``` ## 6. 클래스와 객체 ### 기본 클래스 ```kotlin class Person(val name: String, var age: Int) { // 보조 생성자 constructor(name: String) : this(name, 0) // 초기화 블록 init { println("Person created: $name") } // 메서드 fun introduce() = "안녕하세요, 저는 $name이고 ${age}살입니다." } val person = Person("홍길동", 25) ``` ### 프로퍼티 ```kotlin class Rectangle(val width: Int, val height: Int) { // 계산된 프로퍼티 val area: Int get() = width * height // 커스텀 getter/setter var isSquare: Boolean get() = width == height set(value) { if (value) { // 정사각형으로 만들기 } } // 뒷받침 필드가 있는 프로퍼티 var name: String = "" set(value) { field = value.uppercase() // field는 뒷받침 필드 } } ``` ### 상속 ```kotlin // 기본 클래스 (open으로 상속 허용) open class Animal(val name: String) { open fun sound() = "Some sound" // final로 오버라이드 금지 final fun sleep() = "$name is sleeping" } class Dog(name: String, val breed: String) : Animal(name) { override fun sound() = "Woof!" fun wagTail() = "$name is wagging tail" } // 추상 클래스 abstract class Shape { abstract fun area(): Double // 구체적인 메서드도 가질 수 있음 fun description() = "This is a shape" } class Circle(val radius: Double) : Shape() { override fun area() = Math.PI * radius * radius } ``` ### 데이터 클래스 ```kotlin data class User(val name: String, val email: String, val age: Int) val user1 = User("홍길동", "hong@example.com", 25) val user2 = user1.copy(age = 26) // 복사본 생성 // 자동 생성되는 메서드들 println(user1.toString()) // User(name=홍길동, email=hong@example.com, age=25) println(user1 == user2) // false (구조적 동등성) println(user1.hashCode()) // 해시코드 // 구조 분해 val (name, email, age) = user1 ``` ### 봉인 클래스 (Sealed Class) ```kotlin sealed class Result { data class Success(val data: String) : Result() data class Error(val message: String) : Result() object Loading : Result() } fun handleResult(result: Result) = when (result) { is Result.Success -> "데이터: ${result.data}" is Result.Error -> "오류: ${result.message}" Result.Loading -> "로딩 중..." // else 불필요 (모든 경우가 처리됨) } ``` ### 열거형 ```kotlin enum class Direction { NORTH, SOUTH, EAST, WEST } enum class Color(val rgb: Int) { RED(0xFF0000), GREEN(0x00FF00), BLUE(0x0000FF); fun containsRed() = (this.rgb and 0xFF0000 != 0) } ``` ### 인터페이스 ```kotlin interface Drawable { val color: String // 프로퍼티 fun draw() // 추상 메서드 // 기본 구현이 있는 메서드 fun erase() { println("Erasing...") } } class Circle : Drawable { override val color = "Red" override fun draw() = println("Drawing a circle") } ``` ### 객체 선언과 표현식 ```kotlin // 싱글톤 객체 object DatabaseManager { fun connect() = println("Connected to database") } // 익명 객체 (Java의 익명 클래스) val clickListener = object : View.OnClickListener { override fun onClick(v: View?) { println("Clicked!") } } // 동반 객체 (Java의 static 유사) class MyClass { companion object { const val CONSTANT = "value" fun create() = MyClass() } } ``` ## 7. 널 안전성 ### 널 가능 타입 ```kotlin var name: String = "홍길동" // 널 불가 var nullableName: String? = null // 널 가능 // 안전 호출 연산자 val length = nullableName?.length // 엘비스 연산자 val len = nullableName?.length ?: 0 // 확정 연산자 (!! - 주의해서 사용) val definiteLength = nullableName!!.length // null이면 예외 // 안전 캐스트 val str: String? = obj as? String ``` ### 스코프 함수와 널 처리 ```kotlin val person: Person? = getPerson() person?.let { p -> println("이름: ${p.name}") println("나이: ${p.age}") } // run with 널 체크 person?.run { println("이름: $name") println("나이: $age") } ``` ## 8. 컬렉션 ### 리스트 ```kotlin // 불변 리스트 val fruits = listOf("apple", "banana", "orange") val numbers = listOf(1, 2, 3, 4, 5) // 가변 리스트 val mutableFruits = mutableListOf("apple", "banana") mutableFruits.add("orange") // 배열 val array = arrayOf(1, 2, 3) val intArray = intArrayOf(1, 2, 3) // 기본 타입 배열 ``` ### 세트 ```kotlin val uniqueNumbers = setOf(1, 2, 3, 3, 2) // [1, 2, 3] val mutableSet = mutableSetOf<String>() ``` ### 맵 ```kotlin val ages = mapOf( "홍길동" to 25, "김철수" to 30, "이영희" to 28 ) val mutableAges = mutableMapOf<String, Int>() mutableAges["박민수"] = 32 ``` ### 컬렉션 연산 ```kotlin val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) val evenNumbers = numbers.filter { it % 2 == 0 } val doubled = numbers.map { it * 2 } val sum = numbers.reduce { acc, n -> acc + n } val fold = numbers.fold(0) { acc, n -> acc + n } // 체이닝 val result = numbers .filter { it % 2 == 0 } .map { it * 2 } .take(3) .sum() // 그룹화 val words = listOf("apple", "banana", "apricot", "blueberry") val grouped = words.groupBy { it.first() } // {a=[apple, apricot], b=[banana, blueberry]} ``` ## 9. 제어 구조 ### 조건문 ```kotlin // if 표현식 val max = if (a > b) a else b val result = if (x > 0) { println("Positive") "positive" } else if (x < 0) { println("Negative") "negative" } else { println("Zero") "zero" } ``` ### when 표현식 ```kotlin val x = 3 val result = when (x) { 1 -> "One" 2, 3 -> "Two or Three" in 4..10 -> "Between 4 and 10" is Int -> "It's an integer" else -> "Something else" } // 조건 없는 when val score = 85 val grade = when { score >= 90 -> "A" score >= 80 -> "B" score >= 70 -> "C" else -> "F" } ``` ### 반복문 ```kotlin // for 루프 for (i in 1..5) { println(i) // 1, 2, 3, 4, 5 } for (i in 1 until 5) { println(i) // 1, 2, 3, 4 } for (i in 5 downTo 1 step 2) { println(i) // 5, 3, 1 } // 컬렉션 반복 val fruits = listOf("apple", "banana", "orange") for (fruit in fruits) { println(fruit) } for ((index, fruit) in fruits.withIndex()) { println("$index: $fruit") } // while 루프 var i = 0 while (i < 5) { println(i++) } do { println("At least once") } while (false) ``` ### 반복 제어 ```kotlin for (i in 1..10) { if (i % 2 == 0) continue if (i > 7) break println(i) } // 라벨을 사용한 제어 outer@ for (i in 1..3) { inner@ for (j in 1..3) { if (i == 2 && j == 2) break@outer println("$i, $j") } } ``` ## 10. 예외 처리 ```kotlin fun divide(a: Int, b: Int): Int { return try { a / b } catch (e: ArithmeticException) { println("Division by zero!") 0 } catch (e: Exception) { println("General error: ${e.message}") -1 } finally { println("Division operation completed") } } // 예외 던지기 fun validateAge(age: Int) { if (age < 0) { throw IllegalArgumentException("Age cannot be negative") } } // Nothing 타입 fun fail(message: String): Nothing { throw IllegalStateException(message) } ``` ## 11. 람다와 고차 함수 ### 람다 표현식 ```kotlin val sum = { x: Int, y: Int -> x + y } val square: (Int) -> Int = { it * it } // 단일 매개변수는 it // 후행 람다 val numbers = listOf(1, 2, 3, 4, 5) val doubled = numbers.map { it * 2 } val filtered = numbers.filter { number -> number % 2 == 0 } ``` ### 스코프 함수 ```kotlin data class Person(var name: String, var age: Int) val person = Person("홍길동", 25) // let - 널 체크와 변환 person.let { p -> println("${p.name} is ${p.age} years old") } // run - 객체 구성과 결과 계산 val result = person.run { name = "김철수" age = 30 "Updated person: $name, $age" // 반환값 } // with - 객체와 함께 작업 val description = with(person) { "Name: $name, Age: $age" } // apply - 객체 구성 val newPerson = Person("이영희", 28).apply { age = 29 name = "이영희(수정)" } // also - 추가 작업 val anotherPerson = Person("박민수", 32).also { p -> println("Created person: ${p.name}") } ``` ## 12. 제네릭 ### 기본 제네릭 ```kotlin class Box<T>(val item: T) { fun get(): T = item } val stringBox = Box("Hello") val intBox = Box(42) // 제네릭 함수 fun <T> swap(list: MutableList<T>, i: Int, j: Int) { val temp = list[i] list[i] = list[j] list[j] = temp } ``` ### 변성 (Variance) ```kotlin // 공변성 (out) interface Producer<out T> { fun produce(): T } // 반공변성 (in) interface Consumer<in T> { fun consume(item: T) } // 불변성 interface Processor<T> { fun process(item: T): T } // 사용 지점 변성 fun copy(from: Array<out Any>, to: Array<in Any>) { // from은 읽기만, to는 쓰기만 } ``` ### 제약 조건 ```kotlin // 상한 경계 fun <T : Number> sum(list: List<T>): Double { return list.sumOf { it.toDouble() } } // 여러 제약 조건 fun <T> process(item: T) where T : Comparable<T>, T : Serializable { // T는 Comparable이면서 Serializable이어야 함 } ``` ## 13. 위임 ### 클래스 위임 ```kotlin interface Base { fun doSomething() } class BaseImpl : Base { override fun doSomething() = println("BaseImpl doing something") } class Derived(base: Base) : Base by base { // Base의 구현을 base에게 위임 } val derived = Derived(BaseImpl()) derived.doSomething() // BaseImpl의 구현 호출 ``` ### 프로퍼티 위임 ```kotlin import kotlin.properties.Delegates class User { // 지연 초기화 val name: String by lazy { println("Computing name...") "홍길동" } // 관찰 가능한 프로퍼티 var age: Int by Delegates.observable(0) { property, oldValue, newValue -> println("$oldValue -> $newValue") } // 맵에 위임 val properties = mapOf("email" to "hong@example.com") val email: String by properties } ``` ## 14. 코루틴 (기본) suspend는 함수를 중단했다가 다시 실행할 수 있도록 만들어 비동기 처리를 지원한다. 예를 들어, 아래 예제에서 fetchData 함수에 suspend를 붙임으로써 data 처리 작업과 다른 ui 작업 등을 교차로 수행할 수 있다. ```kotlin import kotlinx.coroutines.* // 기본 코루틴 fun main() = runBlocking { launch { delay(1000L) println("World!") } println("Hello,") } // async와 await suspend fun fetchData(): String { delay(1000L) return "Data" } fun main() = runBlocking { val deferred = async { fetchData() } println("Waiting...") val result = deferred.await() println("Result: $result") } ``` ## 15. 애노테이션과 리플렉션 ### 애노테이션 ```kotlin @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) @Retention(AnnotationRetention.RUNTIME) annotation class MyAnnotation(val value: String) @MyAnnotation("test") class TestClass { @MyAnnotation("method") fun testMethod() {} } ``` ### 리플렉션 ```kotlin import kotlin.reflect.full.* class Person(val name: String, val age: Int) val person = Person("홍길동", 25) val kClass = person::class // 클래스 정보 println("Class name: ${kClass.simpleName}") println("Properties: ${kClass.memberProperties.map { it.name }}") // 프로퍼티 접근 val nameProperty = kClass.memberProperties.find { it.name == "name" } val nameValue = nameProperty?.get(person) ```
목록으로 돌아가기

게시글 삭제

정말로 이 게시글을 삭제하시겠습니까?
삭제된 게시글은 복구할 수 없습니다.