728x90
코틀린으로 API를 개발해야하는 상황이 되었는데, 자바랑 눈에 들어오는 내용이 달라서 익숙치 않네요..
ai 시대의 흐름을 따라 ai를 활용해보면서 클로드한테 코틀린에서 자주 사용하게 되는 필수 문법들을 정리해달라고 해봤습니다!!
저도 공부하며 개발하는 중이라, 아래 정보가 정확한지 아직 검증을 해보지 않았습니다. 공부하며 틀린 내용이 있다면 지속적으로 수정해두겠습니다! 혹시 이 글을 읽으신다면 이 내용을 참고하며 읽어주시고, 혹여 잘못된 내용이 있다면 댓글로 알려주시면 감사하겠습니다. ^ㅁ^
목차
스코프 함수 (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