안드로이드 코틀린 언어 학습 노트 목차

코틀린 기초 — val/var·타입추론·함수·표현식

안드로이드의 공식 주력 언어는 코틀린(Kotlin)이다. 자바와 100% 상호운용되면서도 더 간결하고, 더 안전하고(널 안전), 더 표현력 있는 언어다. 같은 JVM 위에서 돌지만 — 보일러플레이트를 줄이고, 흔한 버그(NullPointerException)를 타입 시스템으로 막고, 함수형·표현식 스타일을 자연스럽게 쓴다. 이 장은 코틀린을 처음부터 — 변수·타입·함수·제어 흐름까지 — 코드로 훑는다. 기준은 Kotlin 2.x(K2 컴파일러). (출처: Kotlin Docs — Basics / Kotlin in Action 2e Ch 1·2.)

val과 var — 불변을 기본으로

코틀린의 변수 선언은 두 키워드뿐이다 — **val(읽기 전용)**과 var(가변).

val name = "Kim"      // 읽기 전용 — 재할당 불가 (자바의 final)
var count = 0         // 가변 — 재할당 가능
count = count + 1     // OK
// name = "Lee"       // ❌ 컴파일 에러: val은 재할당 불가

원칙은 **"일단 val, 꼭 필요할 때만 var"**다. 불변 변수는 추론하기 쉽고, 동시성에 안전하고, 실수를 줄인다. 코틀린 코드가 자바보다 val로 가득 찬 이유다.

주의 — val참조가 불변일 뿐 가리키는 객체 내부가 불변은 아니다. val list = mutableListOf(1)list.add(2)는 된다(참조는 그대로, 내용은 변함). 진짜 불변 컬렉션은 listOf(...).

타입 추론 — 적되, 다 적지 않는다

코틀린은 타입을 추론한다. val name = "Kim"이면 컴파일러가 String임을 안다. 필요하면 명시한다.

val name: String = "Kim"    // 명시 (공개 API·가독성에 권장)
val age = 30                // 추론 → Int
val price = 1000L           // 추론 → Long (접미사 L)
val pi = 3.14               // 추론 → Double

중요한 차이 — 코틀린엔 자바의 원시 타입(int)이 따로 없다. 모든 것이 Int·Double 같은 객체처럼 보이지만, 컴파일러가 가능한 곳에선 원시 타입으로 최적화한다(박싱은 필요할 때만). 그래서 간결함과 성능을 동시에 얻는다.

또 하나 — 암묵적 숫자 변환이 없다. 자바처럼 intlong으로 자동 승격되지 않는다. 명시적으로 변환해야 한다.

val i: Int = 10
val l: Long = i.toLong()   // ✅ 명시 변환 필수
// val l2: Long = i        // ❌ 컴파일 에러

함수 — fun, 단일 표현식, 기본·명명 인자

함수는 fun으로 선언한다. 반환 타입은 매개변수 뒤에 온다.

fun add(a: Int, b: Int): Int {
    return a + b
}

// 단일 표현식 함수 — 본문이 한 식이면 = 으로 줄인다 (반환 타입도 추론)
fun add(a: Int, b: Int) = a + b

// 반환값 없으면 Unit (자바 void) — 생략 가능
fun log(msg: String): Unit { println(msg) }

**기본 인자(default)**와 **명명 인자(named)**가 코틀린의 강력한 무기다 — 자바의 오버로딩 지옥빌더 패턴을 상당 부분 대체한다.

fun createUser(
    name: String,
    age: Int = 0,                 // 기본값
    isAdmin: Boolean = false
) { /* ... */ }

createUser("Kim")                          // age=0, isAdmin=false
createUser("Lee", age = 20)                // 명명 인자 — 순서·가독성 자유
createUser("Park", isAdmin = true)         // 중간 인자 건너뛰기

표현식 지향 — if·when·try가 값이다

코틀린에서 if·when·try는 *문(statement)*이 아니라 식(expression)값을 반환한다. 그래서 자바의 삼항 연산자(?:)가 따로 없다(if가 그 역할).

val max = if (a > b) a else b          // if가 값을 반환
val grade = when (score / 10) {
    10, 9 -> "A"
    8 -> "B"
    in 6..7 -> "C"                     // 범위 조건
    else -> "F"
}

when — 강력한 분기

when은 자바 switch의 강화판이다 — 값·타입·범위·임의 조건 모두 분기할 수 있고, 이라 값을 돌려준다.

fun describe(x: Any): String = when (x) {     // Any = 모든 타입의 최상위
    0 -> "zero"
    is String -> "문자열 길이 ${x.length}"     // 타입 검사 + 스마트 캐스트
    in 1..9 -> "한 자리 수"
    is List<*> -> "리스트"
    else -> "기타"
}

// 인자 없는 when — if-else 사슬을 깔끔하게
val sign = when {
    n > 0 -> "양수"
    n < 0 -> "음수"
    else -> "0"
}

식으로 쓰는 whenelse가 (또는 모든 경우가 망라되면) 필수라 — 빠뜨린 분기를 컴파일러가 잡는다(특히 enum·sealed와 함께).

문자열 템플릿·기본 타입·범위

val name = "Kim"; val age = 30
println("$name is $age")                  // 변수 보간
println("내년엔 ${age + 1}살")             // 식은 ${}
val raw = """여러 줄
    |들여쓰기 제거""".trimMargin()          // 원시 문자열(raw string)

for (i in 1..5) print(i)                  // 1 2 3 4 5 (양끝 포함)
for (i in 1 until 5) print(i)             // 1 2 3 4 (끝 제외)
for (i in 10 downTo 1 step 2) print(i)    // 10 8 6 4 2

가시성·패키지

코틀린의 기본 가시성은 public(자바의 package-private이 아님). 그 외 private(파일/클래스 내부)·protected(하위 클래스)·internal(같은 모듈 내부 — 멀티 모듈 안드로이드에서 모듈 경계를 막는 데 유용, [andarch] 멀티모듈에서 다시).

다이어그램 로딩 중…

정리 — 간결·안전·표현식

코틀린 기초의 핵심은 셋이다 — (1) val 우선의 불변 지향, (2) 타입 추론(+암묵 변환 없음)으로 간결하되 안전, (3) if/when/try가 값을 내는 표현식 지향. 여기에 기본·명명 인자가 더해져 자바의 보일러플레이트가 크게 준다. 다음 장의 널 안전이 코틀린이 자바와 갈리는 가장 큰 한 걸음이다.

한 줄 요약val(불변) 기본·var는 필요할 때. 타입은 추론하되 암묵 변환 없음. 함수는 fun·단일 표현식·기본/명명 인자. if·when값을 내는 식. when은 값·타입·범위·조건을 모두 분기.

(출처: Kotlin Docs — Basic Syntax / Functions / Control Flow / Kotlin in Action 2e Ch 2 / Android Kotlin guide.)

널 안전 — ?·!!·Elvis·플랫폼 타입·스마트 캐스트