이 글은 Kotlin 프로그래밍 언어에서 자주 사용되는 관용구(idiom)들의 모음입니다.
각 관용구에 대한 설명과 예제 코드를 함께 설명합니다.
공식 홈페이지 kotlinlang.org의 내용을 참고합니다.
1. 데이터 클래스 생성 (Create DTOs)
Kotlin에서는 data class를 사용하여 간단하게 DTO(Data Transfer Object)를 만들 수 있습니다.
이는 자동으로 getter, setter, equals(), hashCode(), toString() 등의 메서드를 제공합니다.
data class Customer(val name: String, val email: String)
이 코드는 다음과 같은 기능을 제공하는 Customer 클래스를 생성합니다:
- 모든 속성에 대한 getter (그리고 var의 경우 setter)
- equals()
- hashCode()
- toString()
- copy()
- component1(), component2(), ... (모든 속성에 대해)
2. 함수 매개변수의 기본값 (Default values for function parameters)
함수 정의 시 매개변수에 기본값을 지정할 수 있어, 호출 시 일부 인자를 생략할 수 있습니다.
fun foo(a: Int = 0, b: String = "") { ... }
3. 리스트 필터링 (Filter a list)
filter 함수를 사용하여 리스트에서 조건에 맞는 요소만 선택할 수 있습니다.
val positives = list.filter { x -> x > 0 }
더 간단한 방법:
val positives = list.filter { it > 0 }
4. 컬렉션 내 요소 확인 (Check the presence of an element in a collection)
in 키워드를 사용하여 컬렉션에 특정 요소가 있는지 쉽게 확인할 수 있습니다.
if ("john@example.com" in emailsList) { ... }
if ("jane@example.com" !in emailsList) { ... }
5. String interpolation
$ 기호를 사용하여 문자열 내에 변수 값을 쉽게 삽입할 수 있습니다.
println("Name $name")
6. 안전한 표준 입력 읽기 (Read standard input safely)
readln().toIntOrNull()을 사용하여 안전하게 정수 입력을 받을 수 있습니다.
// 문자열을 읽고 정수로 변환할 수 없는 경우 null을 반환합니다. 예: "안녕하세요!"
val wrongInt = readln().toIntOrNull()
println(wrongInt)
// null
// 정수로 변환 가능한 문자열을 읽고 정수를 반환합니다. 예: 13
val correctInt = readln().toIntOrNull()
println(correctInt)
// 13
7. 타입 검사 (Instance checks)
when 표현식과 is 키워드를 사용하여 객체의 타입을 검사할 수 있습니다.
when (x) {
is Foo -> ...
is Bar -> ...
else -> ...
}
8. 읽기 전용 리스트와 맵 (Read-only list and map)
listOf와 mapOf를 사용하여 변경 불가능한 리스트와 맵을 생성할 수 있습니다.
val list = listOf("a", "b", "c")
val map = mapOf("a" to 1, "b" to 2, "c" to 3)
9. 범위 반복 (Iterate over a range)
다양한 방식으로 숫자 범위를 반복할 수 있습니다.
for (i in 1..100) { ... } // 1부터 100까지 (100 포함)
for (i in 1..<100) { ... } // 1부터 99까지 (100 미포함)
for (x in 2..10 step 2) { ... }
for (x in 10 downTo 1) { ... }
(1..10).forEach { ... }
10. 지연 속성 (Lazy property)
lazy 키워드를 사용하여 필요할 때만 값을 계산하는 속성을 정의할 수 있습니다.
val p: String by lazy { // 값은 첫 접근 시에만 계산됩니다
// 문자열 계산
}
11. 확장 함수 (Extension functions)
기존 클래스에 새로운 메서드를 추가할 수 있습니다.
fun String.spaceToCamelCase() { ... }
"Convert this to camelcase".spaceToCamelCase()
12. 싱글톤 생성 (Create a singleton)
object 키워드를 사용하여 싱글톤을 쉽게 만들 수 있습니다.
object Resource {
val name = "Name"
}
13. Null 안전성 (Null safety)
?., ?:, let 등을 사용하여 null 값을 안전하게 처리할 수 있습니다.
// If-not-null 단축 표현
val files = File("Test").listFiles()
println(files?.size) // files가 null이 아닌 경우 size를 출력
// If-not-null-else 단축 표현
println(files?.size ?: "empty") // files가 null인 경우 "empty" 출력
// null인 경우 실행
val email = values["email"] ?: throw IllegalStateException("Email is missing!")
// null이 아닌 경우 실행
value?.let {
// null이 아닌 경우 이 블록 실행
}
14. 표현식으로서의 try-catch와 if (try-catch and if expressions)
예외 처리와 조건문을 표현식으로 사용할 수 있습니다.
// try-catch 표현식
val result = try {
count()
} catch (e: ArithmeticException) {
throw IllegalStateException(e)
}
// if 표현식
val y = if (x == 1) {
"one"
} else if (x == 2) {
"two"
} else {
"other"
}
15. 간결한 함수 정의 (Single-expression functions)
단일 표현식 함수를 간단히 정의할 수 있습니다.
fun theAnswer() = 42
16. 객체 설정을 위한 apply와 with (Configure properties of an object with apply and with)
객체의 여러 속성을 한 번에 설정하거나 여러 메서드를 호출할 때 사용합니다.
val myRectangle = Rectangle().apply {
length = 4
breadth = 5
color = 0xFAFAFA
}
with(myTurtle) { //100픽셀 정사각형 그리기
penDown()
for (i in 1..4) {
forward(100.0)
turn(90.0)
}
penUp()
}
이 문서는 Kotlin의 특징적인 문법과 기능들을 간결하게 보여주고 있어, Kotlin 초보자부터 중급 개발자까지 유용하게 참고할 수 있는 자료입니다. 각 관용구는 Java와 비교했을 때 Kotlin의 장점을 잘 보여주고 있습니다.
17. 추상 클래스 인스턴스화 (Instantiate an abstract class)
Kotlin에서는 익명 객체를 사용하여 추상 클래스의 인스턴스를 쉽게 생성할 수 있습니다.
abstract class MyAbstractClass {
abstract fun doSomething()
abstract fun sleep()
}
fun main() {
val myObject = object : MyAbstractClass() {
override fun doSomething() {
// ...
}
override fun sleep() {
// ...
}
}
myObject.doSomething()
}
18. Null 안전성 관련 추가 예제 (Additional Null Safety Examples)
If-not-null 단축 표현
val files = File("Test").listFiles()
println(files?.size) // files가 null이 아닌 경우에만 size 출력
If-not-null-else 단축 표현
val files = File("Test").listFiles()
// 간단한 대체값 사용:
println(files?.size ?: "empty") // files가 null이면 "empty" 출력
// 복잡한 대체값 계산을 위해 `run` 사용:
val filesSize = files?.size ?: run {
val someSize = getSomeSize()
someSize * 2
}
println(filesSize)
Null인 경우 예외 발생
val values = ...
val email = values["email"] ?: throw IllegalStateException("Email is missing!")
가능한 빈 컬렉션의 첫 번째 항목 가져오기
val emails = ... // 빈 리스트일 수 있음
val mainEmail = emails.firstOrNull() ?: ""
Null이 아닌 경우 실행
val value = ...
value?.let {
... // value가 null이 아닌 경우 이 블록 실행
}
Null이 아닌 경우 변환
val value = ...
val mapped = value?.let { transformValue(it) } ?: defaultValue
// value나 변환 결과가 null인 경우 defaultValue 반환
19. when 표현식을 사용한 반환 (Return on when statement)
when 표현식을 사용하여 간결하게 값을 반환할 수 있습니다.
fun transform(color: String): Int {
return when (color) {
"Red" -> 0
"Green" -> 1
"Blue" -> 2
else -> throw IllegalArgumentException("Invalid color param value")
}
}
20. 객체의 여러 메서드 호출하기 (with)
with 함수를 사용하면 객체의 여러 메서드를 연속해서 호출할 때 객체 이름을 반복하지 않아도 됩니다.
class Turtle {
fun penDown()
fun penUp()
fun turn(degrees: Double)
fun forward(pixels: Double)
}
val myTurtle = Turtle()
with(myTurtle) { // 100픽셀 정사각형 그리기
penDown()
for (i in 1..4) {
forward(100.0)
turn(90.0)
}
penUp()
}
21. 객체 속성 구성하기 (apply)
apply 함수를 사용하면 객체를 생성하고 즉시 그 속성들을 설정할 수 있습니다.
val myRectangle = Rectangle().apply {
length = 4
breadth = 5
color = 0xFAFAFA
}
22. Java 7의 try-with-resources와 유사한 기능
Kotlin에서는 use 함수를 사용하여 자원을 자동으로 닫을 수 있습니다.
val stream = Files.newInputStream(Paths.get("/some/file.txt"))
stream.buffered().reader().use { reader ->
println(reader.readText())
}
이 예제는 파일을 읽은 후 자동으로 리소스를 닫습니다.
23. 제네릭 타입 정보가 필요한 제네릭 함수
reified 키워드를 사용하여 런타임에 제네릭 타입 정보를 유지할 수 있습니다.
// public final class Gson {
// ...
// public <T> T fromJson(JsonElement json, Class<T> classOfT) throws JsonSyntaxException {
// ...
inline fun <reified T: Any> Gson.fromJson(json: JsonElement): T = this.fromJson(json, T::class.java)
이 예제는 Gson 라이브러리의 fromJson 메서드를 더 간단하게 사용할 수 있게 해줍니다.
24. 두 변수 교환하기
Kotlin에서는 also 함수를 사용하여 두 변수의 값을 쉽게 교환할 수 있습니다.
var a = 1
var b = 2
a = b.also { b = a }
이 코드 실행 후 a는 2가 되고 b는 1이 됩니다.
25. 미완성 코드 표시하기 (TODO)
Kotlin 표준 라이브러리에는 TODO() 함수가 있어 아직 구현되지 않은 코드를 표시할 수 있습니다. 이 함수는 항상 NotImplementedError를 던집니다.
fun calcTaxes(): BigDecimal = TODO("Waiting for feedback from accounting")
TODO() 함수의 반환 타입은 Nothing이므로 어떤 타입이 예상되는 곳에서도 사용할 수 있습니다.
IntelliJ IDEA의 Kotlin 플러그인은 TODO()의 의미를 이해하고 자동으로 TODO 도구 창에 코드 포인터를 추가합니다.
이러한 Kotlin의 관용구들은 코드를 더 간결하고 표현력 있게 만들어줍니다. with와 apply 같은 함수들은 객체를 다룰 때 코드의 가독성을 크게 향상시킵니다. use 함수는 리소스 관리를 더 안전하고 간편하게 만들어주며, reified 키워드를 사용한 제네릭 함수는 타입 안전성을 높여줍니다. TODO() 함수는 개발 과정에서 미완성 코드를 명확히 표시하는 데 도움이 됩니다.
이러한 관용구들을 적절히 활용하면 Kotlin 코드의 품질과 유지보수성을 크게 향상시킬 수 있습니다.
kotlin의 다른 글 :
2024.08.07 - [개발&프로그래밍] - [kotlin] 입문시 알아야 할 8가지 핵심 문법
[kotlin] 입문시 알아야 할 8가지 핵심 문법
Kotlin의 주요 문법 특징들을 간략히 정리한 것입니다.각 항목은 Kotlin의 간결하고 표현력 있는 코드 작성을 지원하는 특징들을 보여줍니다. 아래 문서는 kotlinlang.org 공식 홈페이지를 참조합니다.
observerlife.tistory.com
2024.08.07 - [개발&프로그래밍] - [kotlin] 입문시 알아야 할 7가지 핵심 문법
[kotlin] 입문시 알아야 할 7가지 핵심 문법
Kotlin의 기본적인 문법 요소들을 간략하게 설명하고 있습니다.각 항목은 Kotlin 프로그래밍의 기초를 이해하는 데 중요한 개념들을 포함하고 있습니다. 아래 문서는 kotlinlang.org 공식 홈페이지를
observerlife.tistory.com
'개발&프로그래밍' 카테고리의 다른 글
[kotlin] 코딩 컨벤션 - lambdas, Trailing commas (0) | 2024.08.10 |
---|---|
[kotlin] 코딩 컨벤션 (coding conventions) (0) | 2024.08.09 |
[kotlin] 입문시 알아야 할 8가지 핵심 문법 (0) | 2024.08.07 |
[kotlin] 입문시 알아야 할 7가지 핵심 문법 (0) | 2024.08.07 |
IntelliJ(2023.3.4 버전)에서 항상 파일경로 보이게 설정하기 (0) | 2024.02.20 |
댓글