공식 문서로 보는 Kotlin 문법 찍먹 (1)
업데이트:
공식 문서에 나온 내용을 정리한 글.
자바와 완전히 동일하거나 매우 간단한 내용은 공식 문서를 통해 확인해도 좋을 거 같다. 예시 코드에 대한 결과도 확인할 수 있으니 코드의 플레이 버튼을 눌러보도록 하자.
Basics
Basic syntax
Program entry point
fun main() {
println("Hello world!")
}
or
fun main(args: Array<String>) {
println(args.contentToString())
}
main 함수를 보면 java와는 다르게 접근 제어자, static, return값이 보이지 않는다. 코틀린 접근 제한자(Visibility Modifier)는 public
, protected
, private
, internal
이 있다.
접근 제한자 | 내용 |
---|---|
public | 어디서나 접근 가능, 기본 접근 제한자 |
protected | private 범위에서 자식 클래스 추가 |
pirvate | 파일 또는 클래스 내 |
internal | 같은 모듈 내 |
코틀린에선 따로 명시하지 않으면 public
이다.
Functions
fun sum(a: Int, b: Int): Int {
return a + b
}
fun sum(a: Int, b: Int) = a + b
fun printSum(a: Int, b: Int): Unit {
println("sum of $a and $b is ${a + b}")
}
fun 함수명(파라미터): 반환값 {
...
}
fun 함수명 (파라미터) = ... // 함수 본문을 표현식으로 나타냄
fun 함수명(파라미터): Unit { // 반환값 없을 때 사용, 생략 가능
...
}
Variables
val
읽기 전용은 val
를 사용한다. java의 final
키워드를 붙인 것과 유사하다.
val a: Int = 1 // 즉시 할당
val b = 2 // 타입 명시
val c: Int // 초기화 없이 타입만 명시
c = 3 // 지연 할당
값을 한번만 할당할 수 있다. 자바로 비교하면
final int a = 1;
final int b = 2;
int c;
c = 3;
var
var x = 5 // 'Int' 타입 유추
x += 1
// top level에 변수 선언
val PI = 3.14
var x = 0
fun incrementX() {
x += 1
}
Createing classes and instances
class
키워드를 사용해 class를 정의한다.
class Rectangle(var height: Double, var length: Double) {
var perimeter = (height + length) * 2
}
val rectangle = Rectangle(5.0, 2.0)
println("The perimeter is ${rectangle.perimeter}")
상속은 :
을 통해 나타낸다. 코틀린에서 클래스는 기본으로 final이기 때문에 상속을 하기 위해선 부모 클래스에 open 키워드를 추가해야 한다.
open class Shape
class Rectangle(var height: Double, var length: Double): Shape() {
var perimeter = (height + length) * 2
}
String template
문자열 안에서 외부의 변수를 가져올 때 사용한다. $
를 붙여 사용한다.
var a = 1
val s1 = "a is $a"
a = 2
// 템플릿의 임의 표현식
val s2 = "${s1.replace("is", "was")}, but now is $a"
// 결과 : a was 1, but now is 2
Conditional expressions
fun maxOf(a: Int, b: Int): Int {
if (a > b) {
return a
} else {
return b
}
}
or
fun maxOf(a: Int, b: Int) = if (a > b) a else b
if문 또한 표현식으로 나타낼 수 있다.
for loop
기본적인 foreach 반복문이다. 자바에 비해 보다 간결한 느낌이 든다.
val items = listOf("apple", "banana", "kiwifruit")
for (item in items) {
println(item)
}
인덱스를 이용하고 싶으면 .indices
를 이용한다.
val items = listOf("apple", "banana", "kiwifruit")
for (index in items.indices) {
println("item at $index is ${items[index]}")
}
// 결과
// item at 0 is apple
// item at 1 is banana
// item at 2 is kiwifruit
range를 조절해서 반복문을 실행하고 싶을 땐 step
을 이용한다.
for (i in 1..3) {
println(i)
}
// 결과
// 1 2 3 (println이라 실제론 한 줄에 하나지만 편의상 한 줄에 작성)
for (i in 6 downTo 0 step 2) {
println(i)
}
//결과
// 6 4 2 0
when expression
when
은 여러 분기가 있는 조건식에 사용한다. 자바의 switch
과 유사하다.
fun describe(obj: Any): String =
when (obj) {
1 -> "One"
"Hello" -> "Greeting"
is Long -> "Long"
!is String -> "Not a string"
else -> "Unknown"
}
when이 표현식으로 사용되는 경우 컴파일러가 모든 가능한 경우에 대해 커버하고 있는지를 확신할 수 없는 경우, else 분기는 필수로 있어야 한다. 즉, 모든 가능한 경우에 대한 조건이 없는 경우 else가 필수이다.
Nullable values and null checks
null 값이 가능한 경우, 참조를 nullable로 명시적으로 나타내야한다. Nullable 형식 이름에는 끝에 ?
가 붙는다.
fun parseInt(str: String): Int? {
...
}
위 함수에서 str이 Int값이 없으면 null을 반환하게 된다.
fun printProduct(arg1: String, arg2: String) {
val x = parseInt(arg1)
val y = parseInt(arg2)
//'x * y'를 바로 사용하면 null이 포함될 수 있으므로 오류가 발생한다.
if (x != null && y != null) {
// x, y는 null 검사 후 자동으로 non-nullable로 cast 된다.
println(x * y)
}
else {
println("'$arg1' or '$arg2' is not a number")
}
}
Type checks and automatic casts
is
연산자는 표현식이 type의 인스턴스인지 확인한다. 불변 지역 변수나 property가 특정 type으로 확인된 경우 명시적으로 캐스팅할 필요가 없다.
fun getStringLength(obj: Any): Int? {
if (obj is String) {
// `obj`는 자동으로 `String`으로 캐스팅 된다.
return obj.length
}
// `obj`는 type-checked 분기를 지나서 `Any` type으로 존재한다.
return null
}
정리
코틀린의 기본적인 문법에 대해 공식 문서를 통해 정리해보았다. 물론 더 깊게 들어가면 많은 연산자와 표현 방법들이 존재할테지만 지금은 가볍게 찍먹해보겠다.
이를 기반으로 우아한테크코스 level1 미션이었던 racing-car를 코틀린으로 구현해보려고 한다
댓글남기기