https://kotlinlang.org/docs/idioms.html
Create DTOs (POJOs/POCOs)
코틀린에서는 Data만 가지는 클래스를 Data class라고 따로 정의할 수 있다.
data class User(val name: String, val email: String)
여기에서 POJOs, POCOs의 개념이 나오는데
POJO(Plain Old Java Object): 자바 모델이나 기능, 프레임워크 등을 따르지 않은 자바 오브젝트를 지칭하는 말이다.
POCO(Plain Old CLR Object)는 자바가 아닌 닷넨 오브젝트들을 말한다.
Default values for function parameters
fun foo(a: Int = 0, b: String = "") { ... }
함수를 선언 할 때, 함수에 기본 값을 줄 수 있다.
foo(1, "123) 이렇게 호출 할 수도 있지만, foo(1) 이렇게 호출 할 수도 있는 것이다.
이런 경우에는 미리 선언해둔 기본값이 들어가게 된다.
Filter a list
fun main(){
val list = listOf(1, 2, 3, 4, 5)
val filteredList1 = list.filter{
x -> x > 3
}
println(filteredList1)
val filteredList2 = list.filter{it > 3}
println(filteredList2)
}
리스트에서 조건 filter를 통해, 원하는 값들을 추출 할 수 있다.
이 때 람다 뿐 만 아니라, it을 사용해서도 filter 할 수 있다.
Check the presence of an element in a collection
fun main(){
val emailsList = listOf("trust1204@gmail.com", "trust1204@naver.com")
if ("trust1204@gmail.com" in emailsList) {
println("HI trust1204@gmail.com")
}
}
컬렉션에서 in을 사용하여 해당 값이 컬렉션에 존재하는지 확인 할 수 있다.
String interpolation
fun main(){
val name = "seungkyu"
println("hi $name")
}
$을 통해 문자열 안에 문자열을 끼워 넣을 수 있다.
Instance checks
open class A
class B: A()
fun main(){
val a = A()
when(a){
is B -> println("It is B")
is A -> println("It is A")
else -> println("I dont know")
}
}
is [Class name]을 통해 해당 클래스의 인스턴스인지 검사 할 수 있다.
Read-only list
val list = listOf(1, 2, 3)
이렇게 읽을 수만 있는 리스트를 생성할 수 있다.
이 데이터는 add, put 과 같은 함수로 추가 혹은 수정이 불가능하다.
Read-only map
val map = mapOf("a" to 1, "b" to 2, "c" to 3)
위와 마찬가지로 읽을 수만 있는 map을 생성할 수 있다.
to로 key와 value를 mapping 한다.
Access a map entry
fun main(){
val map = mapOf("a" to 1, "b" to 2, "c" to 3)
println(map["a"])
}
이런 식으로 map에 접근하여 데이터를 읽을 수 있다.
Traverse a map or a list of pairs
fun main(){
val map = mapOf("a" to 1, "b" to 2, "c" to 3)
for((k,v) in map){
println("$k = $v")
}
}
map의 key와 value를 반복문으로 한 번에 읽어올 수 있다.
Iterate over a range
for (i in 1..10) { ... } //includes 10
for (i in 1..<10) { ... } //not include 10
for (x in 2..10 step 2) { ... }
for (x in 10 downTo 1) { ... }
(1..10).forEach { ... }
..과 <을 이용해서 iterate의 범위를 정할 수 있다.
Lazy property
fun main(){
val p: String by lazy {
if(0 > 1)
"Hello World"
else
"Hi world"
}
}
val 타입에서 by lazy로 실행된 이후에 값을 할당 할 수 있다.
Create a singleton
Object Seungkyu{
val name = "seungkyu"
}
Object 키워드를 사용하여 싱글톤 객체를 만들 수 있다.
Use inline value classes for type-safe values
@JvmInline
value class UserId(private val id: String)
value 클래스로 만들면, 클래스가 데이터를 직접 참조하기 때문에 객체 생성에 대한 cost를 아낄 수 있다고 한다.
Instantiate an abstract class
abstract class InstantiateAnAbstractClass {
abstract fun doSomething()
abstract fun sleep()
}
fun main(){
val myObject = object : InstantiateAnAbstractClass() {
override fun doSomething() {
println("It is doSomething")
}
override fun sleep() {
println("It is sleeping")
}
}
myObject.doSomething()
}
이렇게 추상 클래스를 바로 만들 수 있다.
If-not-null shorthand
fun main(){
val a: String? = "seungkyu!!"
println(a?.length)
}
null 가능 변수에 ?. 을 붙여서 만약 null이 아니면 가져올 값을 지정할 수 있다.
If-not-null-else shorthand
fun main(){
val a: String? = null
println(a?.length ?: "hello!!")
}
null이 아닐 때 뿐만 아니라, null 일 때 가져올 값을 지정할 수 있다.
만약 ?: 앞의 값이 null이라면 뒤에 있는 값으로 가져오게 된다.
Execute a statement if null
fun main(){
val values= mapOf<String, Int>()
println(values["a"] ?: throw NullPointerException())
}
?: 를 통해 null 일 때 Exception을 throw 할 수 있다.
Get first item of a possibly empty collection
fun main(){
val emails = listOf<String>()
val mainEmail = emails.firstOrNull()
println(mainEmail)
}
이런 식으로 first item을 가져오거나 null을 가져 올 수 있다.
Execute if not null
fun main(){
val value1 = "String"
val value2:String? = null
value1?.let {
println(it)
}
value2?.let {
println(it)
}
}
?.let을 이용하여 해당 데이터가 null이 아닐 때 실행할 값을 실행할 수 있다.
Return on when statement
fun main(){
println(myFunc(3))
}
fun myFunc(value: Int): String{
return when(value){
1 -> "one"
2 -> "two"
3 -> "three"
else -> "no"
}
}
이렇게 함수 Return 부분에서 when을 사용하여 값을 return 할 수 있다.
이 때, 어떠한 경우에도 값이 return 될 수 있도록 꼭 when을 지정해주어야 한다.
try-catch expression
fun main(){
val result = try{
throw NullPointerException()
}catch (e: NullPointerException){
1
}
println(result)
}
값을 할당 할 때에도, try-catch Expression을 사용하여 값을 대입할 수 있다.
Builder-style usage of methods that return Unit
fun main(){
arrayOfMinusOnes(10).forEach { print("$it ") }
}
fun arrayOfMinusOnes(size: Int): IntArray {
return IntArray(size).apply { fill(-1) }
}
return 할 때에도, 자바의 Builder 스타일을 사용해 값을 반환 할 수 있다.
Single-expression functions
fun theResult1() = 1111
fun theResult2(value: Int) = when(value){
1 -> "one"
2 -> "two"
else -> "other"
}
fun main(){
println(theResult1())
println(theResult2(1))
}
함수를 이렇게 하나의 표현식으로도 작성할 수 있다.
Call multiple methods on an object instance (with)
class Bird{
fun fly(){
println("Bird fly")
}
fun go(x: Int, y: Int){
println("Bird go $x $y")
}
}
fun main(){
val myBird = Bird()
with(myBird){
fly()
for(i in 1..3){
go(i,i)
}
}
}
with를 사용해서 하나의 인스턴스에서 다양한 함수들을 호출 할 수 있다.
Generic function that requires the generic type information
inline fun <reified T: Any> hello(value: String): T = value as T
fun main() {
}
타입 정보를 같이 받는 Generic Function을 구현 할 수도 있다.
Mark code as incomplete (TODO)
fun main(){
println("Hello Kotlin")
TODO("아직이요")
}
TODO를 이용하여 아직 작성하지 않은 코드라고 알릴 수 있다.
자동으로 코드를 삽입해주어서, 실행이 가능하다.
물론 TODO()의 코드에 도착하면 그때는 에러가 발생한다.
'백엔드 > 코틀린' 카테고리의 다른 글
Concepts:Control flow (1) | 2024.10.05 |
---|---|
Basic syntax (0) | 2024.09.28 |
코틀린 시작 (0) | 2024.09.28 |