kotlin을 예전에 간단히 공부하고 써먹었는데, 다시한번 공부하고 기록을 남길겸 작성한다.
공부는 Kotlin In Action 라는 책과 공식사이트를 참고로 했다. 코드 실행은 intelliJ를 사용.
주 사용처는 서버개발을 위한 언어로 Kotlin 을 도입해보기 위함.
정리는 책을 읽은 순서대로 작성하고, 예제로 작성한 코드에서 패키지는 모두 생략.
Kotlin은 기본적으로 jvm위에서 동작 (java 와 혼용에서 사용가능)
보통 Gradle을 사용해서 build하는데, gradle에 코틀린 관련 plugin만 작성해주면 기본적인 사용 가능.
프로젝트를 구성할때, 디렉토리 구조를 java와 같은 방식으로 구조를 짜는걸 추천 (그렇지 않으면, 혼용하거나, 마이그레이션할때 이슈가 생길 수 있음)
kotlin은 java와 다르게 클래스명과 파일명을 다르게 해도되고, 패키지명도 디렉토리 위치랑은 상관이 없다. (하지만 위에 언급한것 처럼 java와 맞추는걸 추천)
kotlin gradle 세팅
plugins {
id 'org.jetbrains.kotlin.jvm' version '1.4.10'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib"
implementation "org.jetbrains.kotlin:kotlin-test"
implementation "org.jetbrains.kotlin:kotlin-test-junit"
}
kotlin test 실행
import kotlin.test.Test
class KotlinTest {
@Test
fun hello () {
print("Hello")
}
}
kotlin-test-junit 라이브러리가 있어야 동작하고, jUnit은 클래스 안에 함수를 작성해야 동작하는것 같다. (kotlin은 .kt라는 확장자를 사용하는데, 파일안에 반드시 class가 있어야하는건 아니다.)
kotlin main 실행
Application.kt
fun main(args: Array<String>) {
println("Hello")
}
위 코드는 java로 변환한다면 아래와 같다.
public class Application {
public static void main(String[] args) {
System.out.println("Hello");
}
}
java의 public static void main(String[] args) 와 같다고 보면된다.
kotlin은 main함수가 class안에 있어야하는게 아니기 때문에 위와 같이 3줄만 작성하면 된다.
위의 코드로 유추해 볼 수 있는것은
1. kotlin의 기본 접근자는 public 이어서 생략이 가능하다.
2. kotlin 의 매개변수와 type선언은 java와 반대이다.
3. kotlin 함수는 반환형이 생략이 가능하다.
4. kotlin main함수는 class안에 작성되지 않았기 때문에, static이라는 keyword가 필요없다.
이정도 인것 같다.
식(expression),문(statement)
kotlin에서 if,when(java의 switch)... 은 식이다. (java에서는 문이다.)
식과 문의 차이점은
식은 값을 만들어 내기 때문에, 반환값 및 대입같은걸 필요로 할때 바로 사용할 수 있다는 점이다. (문은 안된다.)
예를들어 java에서는
public class Test {
public int getMaxValue(int a, int b) {
if (a > b) return a;
return b;
}
}
if를 사용한다면 위와 같이 해야하지만,
kotlin에서는
fun getMaxValue(a: Int, b: Int) = if (a>b) a else b
와 같이 값을 만들어 낸다. 문에서 식으로 변경되었기 때문에, 더 간략한 코딩이 가능할것 같다.
kotlin은 smart cast라는기능이 있는데, 타입변환 및 캐스팅을 편리하게 해주는 기능이다.
interface Expr
import kotlin.test.Test
class Num(val value: Int): Expr
class Sum(val left: Expr, val right: Expr): Expr
fun eval(e: Expr): Int = when (e) {
is Num -> e.value
is Sum -> eval(e.left) + eval(e.right)
else -> throw Error("알 수 없는 타입")
}
class ExprTest {
@Test
fun test() {
// input: 1+2+4
val result = eval(Sum(Sum(Num(1), Num(2)), Num(4)))
println("result:${result}")
}
}
is라는 키워드는 java의 instanceof와 비슷한 기능이다.
smart cast라는건 코딩으로 직접 형변환을 안해도 컴파일러가 자동으로 추론해 주는걸 뜻한다.
type을 통일 시키려고 Expr이라는 interface라는걸 사용해서 위와 같이 형변환에 대한 캐스팅을 안해도 변수 그대로 사용할 수 있다.
단 smart cast는 input이 val(final)이어야 하는 제약조건이 있다.
반복문
kotlin은 for(int i =0; i < size; i++) 와 같은 반복문을 지원하지않고, enhanced for문만을 지원한다.
// 1 ~ 10
fun oneToTenLoop() {
val oneToTen = 1..10
for (i in oneToTen) println(i)
}
// 0, 2,4 ... 10
fun zeroToTenEvenLoop() {
val zeroToTen = 0..10
for (i in zeroToTen step 2) println(i)
}
// 10, 8, 6 ... 2
fun oneToTenEvenLoopReverse() {
for (i in 10 downTo 1 step 2) println(i)
}
// 1 ~ 9
fun oneToNineLoop() {
for (i in 1 until 10) println(i)
}
위와 같이 비슷하지만 다양하게 지원을 한다.