JetBrains에서 개발한 JVM 언어
Kotlin의 원시 타입은 래퍼 타입으로 다룸
Byte
, Short
, Int
, Long
, Float
, Double
is
연산자로 타입을 확인하면 이후 자동으로 형변환해줌
val
변수와 일부 상황의 var
변수에서 사용 가능Kotlin에는 checked exception
이 없음
checked exception
이 생산성과 코드 품질을 떨어트리기 때문@Throws
사용모든 클래스가 상속하는 클래스 (Java의 Object
에 대응)
'값이 존재할 수 없음'을 표현하며, 모든 클래스의 자식인 클래스
Kotlin의 클래스는 기본적으로 final
이며 상속이 불가능함
open
키워드를 적용해야 함Kotlin의 멤버 프로퍼티와 함수는 기본적으로 final
이며 오버라이딩이 불가능함
open
키워드를 적용해야 함override
키워드로 명시해야 함sealed
클래스를 적용하면, 컴파일 이후 더 이상 상속이 불가능함
enum
처럼 활용할 수 있음프로퍼티 혹은 변수가 null을 허용하지 않고 늦게 초기화되고 싶을 때 사용
레퍼런스.isInitialized
로 초기화 여부 확인외부 접근을 제한하는 키워드
private
protected
internal
: 동일 모듈 내에서만 접근 가능public
Decorator 패턴을 구현할 필요 없이, 기존 클래스에 프로퍼티나 함수를 추가함
데이터 보관을 목적으로 기본적인 기능과 유용한 함수를 갖는 클래스
val
혹은 var
이어야 함abstract
나 open
, sealed
, inner
불가능equals()
/ hashCode()
toString()
componentN()
copy()
Java의 Generics와 닮아있지만, 더 엄격하고 안전함
Declaration-site variance
와 Type projections
기능이 존재함interface Source<out T> {
fun nextT(): T
}
클래스 정의 시 타입 인자의 공변성을 미리 정의할 수 있음
out
: 공변 (only produced), Java의 <? extends T>
in
: 반공변 (only consumed), Java의 <? super S>
fun copy(src: Array<out Any>, dest: Array<Any>) { ... }
공변성을 미리 정의할 수 없는 경우(e.g. Array
), 사용 시에 투영할 수 있음
out
: 값을 얻기 위해 투영함 (only produced)in
: 값을 넣기 위해 투영함 (only consumed)타입 인자에 대해 모를 때, 모든 타입을 안전하게 수용하기 위해 사용함
Foo<out T : TUpper>
: Foo<*>
가 Foo<out TUpper>
와 같음Foo<in T>
: Foo<*>
가 Foo<in Nothing>
과 같음Foo<T : TUpper>
: Foo<*>
가 읽을 땐 Foo<out TUpper>
, 쓸 땐 Foo<in Nothing>
과 같음fun <T : Comparable<T>> sort(list: List<T>) { ... }
Java의 <T extends S>
에 대응하는 Upper bounds 기능
Generic은 compile-time 검증을 위한 기능이며, 컴파일 시 Generic 정의가 지워짐
inline reified functions
는 타입 인자 정보를 기억함class Derived(b: Base) : Base by b
Delegation 패턴을 쉽게 작성할 수 있도록 하는 기능
class Example {
var p: String by Delegate()
}
by
키워드로, getter와 setter의 기능을 위임하는 프로퍼티 기능
Lazy properties
: 최초 호출 시 연산하고, 결과를 캐싱함 (lazy()
)Observable properties
: 프로퍼티의 수정을 감지하고 동작을 수행함 (Delegates.observable()
)Vetoable properties
: 프로퍼티의 수정 전 동작을 수행함 (Delegates.vetoable()
)by this::delegate
)나 Map(by map
)에 위임할 수도 있음infix fun Int.shl(x: Int): Int { ... }
// calling the function using the infix notation
1 shl 2
// is the same as
1.shl(2)
.
과 괄호 없이 호출할 수 있는 함수
val eps = 1E-10 // "good enough", could be 10^-15
// tailrec expression
tailrec fun findFixPoint(x: Double = 1.0): Double =
if (Math.abs(x - Math.cos(x)) < eps) x else findFixPoint(Math.cos(x))
// is the same as
private fun findFixPoint(): Double {
var x = 1.0
while (true) {
val y = Math.cos(x)
if (Math.abs(x - y) < eps) return x
x = Math.cos(x)
}
}
tailrec
키워드를 적용하면, 재귀 호출을 반복문으로 바꿔줌
StackOverflow
에러를 예방할 수 있음inline fun <T> lock(lock: Lock, body: () -> T): T { ... }
컴파일 시 함수 호출을 함수 내용으로 변환시켜줄 함수
inline
을 활용하기 좋음noinline
키워드를 적용하여 해제함)inline
함수에서의 반환은 외부 함수의 반환으로 사용할 수 있음 (non-local returns
)non-local return
을 적용하려면 crossinline
키워드를 적용해야 함fun postItem(item: Item) {
launch {
val token = preparePost()
val post = submitPost(token, item)
processPost(post)
}
}
suspend fun preparePost(): Token {
// makes a request and suspends the coroutine
return suspendCoroutine { /* ... */ }
}
비동기 Non-blocking 프로그래밍을 위한 API
import com.example.html.*
fun result() =
html {
head {
title {+"XML encoding with Kotlin"}
}
body {
h1 {+"XML encoding with Kotlin"}
p {+"this format can be used as an alternative markup to XML"}
// an element with attributes and text content
a(href = "http://kotlinlang.org") {+"Kotlin"}
// mixed content
p {
+"This is some"
b {+"mixed"}
+"text. For more see the"
a(href = "http://kotlinlang.org") {+"Kotlin"}
+"project"
}
p {+"some text"}
// content generated by
p {
for (arg in args)
+arg
}
}
}
Domain-specific language; 특정 도메인에 특화된 언어
Kotlin에서 제공하는 기본 컬렉션 클래스들
if (i in 1..4) { // equivalent of 1 <= i && i <= 4
print(i)
}
수의 범위를 표현하는 클래스
first
와 last
, step
으로 Iteration을 정의 (Java의 for문처럼)val oddNumbers = generateSequence(1) { it + 2 } // `it` is the previous element
println(oddNumbers.take(5).toList())
//println(oddNumbers.count()) // error: the sequence is infinite
수열을 표현하는 클래스
Iterable
과 달리 여러 연산을 한 번에 수행함 (executed lazily)함수 | 객체 참조 | 반환 값 | Extension function 여부 |
---|---|---|---|
let | it | Lambda result | Yes |
run | this | Lambda result | Yes |
run | - | Lambda result | No (Context object 없이 호출) |
with | this | Lambda result | No (Context object를 인자로 받음) |
apply | this | Context object | Yes |
also | it | Context object | Yes |
람다를 활용해 객체를 조작하는 let
과 run
, with
, apply
, also
함수
let
let
apply
run
run
also
with