PROGRAMMING/Kotlin

[Kotlin] Kotlin API 개발 필수 문법 정리 with Claude

seulda 2025. 11. 24. 18:06
728x90

코틀린으로 API를 개발해야하는 상황이 되었는데, 자바랑 눈에 들어오는 내용이 달라서 익숙치 않네요..

ai 시대의 흐름을 따라 ai를 활용해보면서 클로드한테 코틀린에서 자주 사용하게 되는 필수 문법들을 정리해달라고 해봤습니다!!

저도 공부하며 개발하는 중이라, 아래 정보가 정확한지 아직 검증을 해보지 않았습니다. 공부하며 틀린 내용이 있다면 지속적으로 수정해두겠습니다! 혹시 이 글을 읽으신다면 이 내용을 참고하며 읽어주시고, 혹여 잘못된 내용이 있다면 댓글로 알려주시면 감사하겠습니다. ^ㅁ^


목차

  1. 스코프 함수 (Scope Functions)
  2. Null 안전 관련
  3. 컬렉션 함수
  4. String 함수
  5. 람다 및 고차 함수
  6. 유용한 Kotlin 기능
  7. API 개발 실전 예시

스코프 함수 (Scope Functions)

Kotlin의 스코프 함수는 객체의 컨텍스트 내에서 코드 블록을 실행할 수 있게 해줍니다.

let

  • 반환값: 람다 결과
  • 참조 방식: it
  • 용도: null 안전 호출과 함께 사용
    val result = value?.let {
      processValue(it)
    }
    

// 실전 예시
user?.email?.let { email ->
sendEmail(email)
}


## run
- **반환값**: 람다 결과
- **참조 방식**: this
- **용도**: 객체 초기화 및 결과 계산
```kotlin
val result = service.run {
    connect()
    fetchData()
}

with

  • 반환값: 람다 결과
  • 참조 방식: this
  • 용도: non-null 객체에서 여러 메서드를 간결하게 호출
    val result = with(user) {
      println(name)
      println(age)
      email
    }

apply

  • 반환값: 객체 자신
  • 참조 방식: this
  • 용도: 객체 초기화 시에 가장 많이 사용
    val user = User().apply {
      name = "John"
      age = 30
      email = "john@example.com"
    }

also

  • 반환값: 객체 자신
  • 참조 방식: it
  • 용도: 로깅, 디버깅 등 부가적인 작업
    val user = getUser().also {
      logger.info("User fetched: ${it.name}")
    }

Null 안전 관련

Elvis 연산자 (?:)

val name = user?.name ?: "Unknown"
val length = text?.length ?: 0

Safe Call (?.)

val length = text?.length
val upperCase = user?.name?.uppercase()

Non-null Assertion (!!)

val length = text!!.length  // null이면 예외 발생

takeIf / takeUnless

val positive = number.takeIf { it > 0 }
val negative = number.takeUnless { it > 0 }

?.let

user?.let {
    println(it.name)
    saveUser(it)
}

컬렉션 함수

변환 함수 (map, flatMap, mapNotNull, mapIndexed)

map

각 요소를 변환하여 새로운 리스트 생성

val numbers = listOf(1, 2, 3)
val doubled = numbers.map { it * 2 }  // [2, 4, 6]

val users = listOf(User("John", 30), User("Jane", 25))
val names = users.map { it.name }

flatMap

중첩된 컬렉션을 평탄화

val nested = listOf(listOf(1, 2), listOf(3, 4))
val flat = nested.flatMap { it }  // [1,2,3,4]

mapNotNull

null 제외하고 변환

val strings = listOf("1", "2", "abc", "3")
val numbers = strings.mapNotNull { it.toIntOrNull() }

mapIndexed

인덱스를 함께 사용하는 변환

val list = listOf("a", "b", "c")
val indexed = list.mapIndexed { index, value -> "$index: $value" }

필터링 함수

filter

val even = listOf(1,2,3,4).filter { it % 2 == 0 }

filterNot

val odd = listOf(1,2,3,4).filterNot { it % 2 == 0 }

filterNotNull

mixed.filterNotNull()

filterIsInstance

val strings = mixed.filterIsInstance<String>()

partition

조건에 따라 두 그룹으로 나누기

val (neg,pos)=numbers.partition{it<0}

그룹화 및 집계

groupBy

val byLength = words.groupBy { it.length }

groupingBy + eachCount

val counts = words.groupingBy { it }.eachCount()

associate / associateBy

users.associateBy { it.id }
users.associate { it.id to it.name }

집합 및 검색 함수

distinct / distinctBy

numbers.distinct()
users.distinctBy { it.email }

union / intersect / subtract

list1.union(list2)
list1.intersect(list2)
list1.subtract(list2)

find / findLast

numbers.find { it > 3 }
numbers.findLast { it > 3 }

any / all / none

numbers.any { it > 3 }
numbers.all { it > 0 }
numbers.none { it < 0 }

contains / in

2 in listOf(1,2,3)

집계 함수

numbers.sum()
numbers.count()
numbers.maxOrNull()
numbers.minOrNull()
numbers.average()

정렬

numbers.sorted()
numbers.sortedDescending()
users.sortedBy { it.age }

String 함수

text.trim()
text.split(",")
text.substringBefore(":")
text.substringAfter(":")
text.uppercase()
text.lowercase()
"123".toIntOrNull()

람다 및 고차 함수

it

list.filter { it > 1 }

to

val pair = "name" to "John"

체이닝

val user = User()
    .apply { name="John"; age=30 }
    .also { logger.info("Created user: ${it.name}") }

함수 타입

val sum:(Int,Int)->Int={a,b->a+b}
fun calc(a:Int,b:Int,op:(Int,Int)->Int)=op(a,b)

유용한 Kotlin 기능

중위 함수

infix fun Int.times(str:String)=str.repeat(this)
3 times "Ha"

구조 분해

val (name,age)=User("John",30)
for((k,v) in map) println("$k -> $v")

범위

1..10
1 until 10
10 downTo 1

when

when(x){
 1->"one"
 in 3..10->"range"
 else->"other"
}

타입 체크 및 캐스팅

if(obj is String) println(obj.length)
val str=obj as? String

lateinit / lazy

lateinit var user:User
val value by lazy { compute() }

확장 함수

fun String.addExclamation()="$this!"
"Hello".addExclamation()

API 개발 실전 예시

요청 검증 및 처리

fun processRequest(params: Map<String, String>): Response {
    return params
        .takeIf { it.isNotEmpty() }
        ?.let { validParams ->
            validParams["userId"]
                ?.takeIf { it.isNotBlank() }
                ?.let { userId ->
                    userRepository.findById(userId)
                        ?.let { user -> Response.success(user) }
                        ?: Response.error("사용자를 찾을 수 없습니다")
                }
                ?: Response.error("유효하지 않은 userId입니다")
        }
        ?: Response.error("파라미터가 비어있습니다")
}

데이터 변환 및 그룹화

fun getUserReport(users: List<User>): Map<String, List<String>> {
    return users
        .filter { it.age >= 18 }
        .filter { it.email.isNotBlank() }
        .distinctBy { it.email }
        .groupBy { it.department }
        .mapValues { (_, userList) ->
            userList
                .sortedBy { it.name }
                .map { "${it.name} (${it.age}세)" }
        }
}

Sequence 활용

data.asSequence()
    .filter { it.isNotBlank() }
    .map { it.trim().lowercase() }
    .distinct()
    .sorted()
    .take(100)
    .toList()
728x90