3. Operators & expressions

연산자와 표현식

1) 기본 연산자

  • 산술: +, -, *, /, %

  • 비교: >, <, >=, <=

  • 논리: &&, ||, !

  • 대입: =, +=, -=

👉 자바와 같지만, 코틀린에서는 모두 함수 호출로 해석됩니다. 예: a + ba.plus(b)


2) 동등성 / 동일성

  • == → 값 비교 (Java의 equals)

  • === → 참조 비교 (Java의 ==)

val s1 = "hello"
val s2 = "hello"
println(s1 == s2)   // true (내용 비교)
println(s1 === s2)  // true/false (참조 비교, JVM intern 여부에 따라 달라짐)

3) 널 안전 관련 연산자 (복습)

  • Safe call: ?.

  • Elvis: ?:

  • Not-null 단언: !!

👉 이전 파트에서 다룬 내용이지만, 연산자 시스템의 일부로 이해하세요.


4) 타입 검사 연산자

  • is → 타입 검사 (Java의 instanceof)

  • !is → 부정

if (obj is String) {
    println(obj.length)  // 스마트 캐스트
}

5) 포함 여부 연산자

  • in, !in → 컬렉션/범위 안에 포함되는지 검사

val list = listOf(1, 2, 3)
println(2 in list)   // true
println(4 !in list)  // true

for (i in 1..5) {    // 1 <= i <= 5
    println(i)
}

6) 범위와 진행(Range & Progression)

  • 1..10 → 1에서 10까지 포함

  • until → 끝 값 제외 (0 until 10 → 0~9)

  • downTo, step

for (i in 10 downTo 1 step 2) {
    println(i)  // 10, 8, 6, ...
}

7) 연산자 오버로딩

  • 클래스에 특정 함수 이름을 정의하면 연산자를 재정의 가능

  • 예: plus, minus, times, div, get, set, compareTo

data class Point(val x: Int, val y: Int) {
    operator fun plus(other: Point) = Point(x + other.x, y + other.y)
}

val p1 = Point(1,2)
val p2 = Point(3,4)
println(p1 + p2) // Point(x=4, y=6)

👉 자바에는 없는 기능. 👉 다만 남용하지 말고, “의미상 자연스러운” 경우에만 쓰세요.


8) 표현식(Expression) vs 문(Statement)

코틀린의 큰 차별점: 대부분의 제어문이 “표현식”. 즉, 값을 반환할 수 있습니다.

if 표현식

val max = if (a > b) a else b

when 표현식

val desc = when(x) {
    1 -> "one"
    in 2..5 -> "small range"
    else -> "other"
}

👉 자바의 switch보다 강력. 타입 검사, 범위, 여러 조건 동시 처리 가능.


9) 실무 패턴 예시

A. 안전한 컬렉션 접근

val name = userList.firstOrNull()?.name ?: "Unknown"

→ 자바의 if-null-check + 삼항연산자 대신 한 줄.

B. 도메인 모델 연산자

operator fun Money.plus(other: Money) = Money(this.amount + other.amount)

→ 도메인 주도 설계(DDD)에서 Value Object를 자연스럽게 다룰 수 있음.

C. when으로 sealed class 분기

sealed class Result
data class Success(val data: String): Result()
object Failure: Result()

fun handle(r: Result) = when(r) {
    is Success -> println(r.data)
    Failure -> println("fail")
}

→ 컴파일러가 exhaustiveness 검사 → 실수 방지.

Last updated