Kotlin 문법

짱구·2023년 3월 9일
0

kotlin

목록 보기
1/8
post-thumbnail

코틀린에서 문법은 자바와 정말 많이 유사합니다.

변수 선언

일단 코틀린에서는 변수를 선언 할 때 val과 var로 선언을 합니다.

  • val = value
    • val로 선언을 하면 상수로 선언을 하는것이며 값이 변경 될 수 없습니다.
  • var = variable
    • var로 선언을 하면 변수로 선언을 하는것이며 값이 변경 될 수 있습니다.

코틀린은 변수와 상수로 선언을 하고 변수의 type을 지정을 해줘도 되고 해주지 않아도 자동으로 유추하여 type에 맞게 설정됩니다.
또 코틀린은 자바와 다르게 세미콜론;이 필수가 아니기에 사용해도 되고 사용하지 않아도 됩니다.

// 상수
val a : String = "변수"
val b : Int = 1
   
var c : Int = 0; // 변수
c = 3

var d : Int = 1
d = "오류" // type이 다르면 재할당 불가능

코틀린은 변수를 선언 할 때 Top Level에 위치 시킬 수 있습니다.
자바와 같은 경우는 class안에 있어야 변수가 선언이 되는데 비해 코틀린은 함수 밖이나 클래스 밖에서 변수를 선언 할 수 있습니다.

var x : Int = 5

fun main() {
    x+=1;
    println(x)
}

함수의 구성 및 선언

일반적인 function 선언이며 매개변수와 return type을 명시해줬습니다.

fun sum(a : Int, b : Int) : Int {
    return a + b
}

표현식이라는 코틀린 문법이며 마찬가지로 매개변수와 return type을 명시해줬습니다.
일반적인 function과의 차이점은 몸통 : {중괄호}가 생략되었고 return을 명시하지 않았습니다.

// 표현식
fun minus(a : Int, b : Int) : Int = a - b

표현식을 응용하면 코틀린에서 자료형을 명시하지 않고 변수를 선언 할 때 처럼 function에서 반환 타입을 명시하지 않았습니다.

// 표현식 & 반환 타입 생략
fun multiply(a : Int, b : Int) = a * b

몸통{중괄호}이 있는 함수는 반환 타입을 제거하면 컴파일 오류가 생기기에 간단한 표현식이 아니라면 몸통{중괄호}을 사용하고 꼭 반환 타입과 return을 명시해줘야합니다.

fun divide (a : Int, b : Int) : Int {
    return a/b
}

반환 타입이 없는 함수는 반환 타입이 Unit이 되며 Unit은 생략 될 수 있고 정의를 하지 않아도 됩니다.
자바에서의 void와 같은 의미를 가지는것 같습니다.

// 반환 타입이 없는 함수는 Unit 반환
fun mod(a : Int, b : Int) : Unit {
    println("$a % $b = ${a%b}")
}

Default Parameter

코틀린에서는 default parameter라는 기능을 제공해줍니다.
default parameter는 function에 매개변수가 없을 때 파라미터에 값을 default 값으로 전달해주는 기능입니다.
아래 코드에서는 매개변수로 String type의 인자를 받고 값을 받지 못하면 parameter의 value는 "반갑습니다"가 넘어가게됩니다.

fun sendMessage(message : String = "반갑습니다"){
    println(message)
}

fun main(){
    sendMessage()
    sendMessage("Hello")
}

출력::::
반갑습니다
Hello

자바에서는 default parameter를 지원해주지 않기에 아래 코드와 같이 매우 지저분한 코드가 생성이 되어 가독성이 좋지 않습니다.

public void sendMessage(String message){
    if (message == null || message.length() == 0){
        System.out.println("반갑습니다");
    }else {
        System.out.println(message);
    }
}

Named Argument

코틀린에서는 named arguemnt라는 기능을 지원해줍니다.
named arguemnt는 function 아규먼트에 name을 지정해서 바인딩을 할 수 있게 도와주는 기능입니다.
자바에서는 named arguemnt 지원해주지 않아 아규먼트를 전달할 때 순서에 맞게 전달을 해야하는데 비해 코틀린은 순서에 맞춘 아규먼트 방식과 named arguemnt를 통한 특정 인수를 지정하는 방식 두 가지를 다 지원해줍니다.
named arguemnt와 default parameter를 모두 사용할 수 있는 코틀린 코드는 아래와 같이 매우 유용하고 가독성 좋게 사용 할 수 있습니다.

fun log(level: String = "INFO", message: String = "디버그 로그"){
    println("[$level]$message")
}

fun main( ) {

    log(message = "인포 로그")    // message만 값 입력 - level은 default parameter가 적용

    log(level = "DEBUG", "디버그 로그")	  // level만 값 명시, message 부분은 순서로 바인딩

	log("WARN", "워닝 로그")    //순서로 바인딩

	log(level = "ERROR", message = "에러 로그")    // 값 모두 
}log("디버그 로그", level = "DEBUG")와 같이 순서로 level이 들어가야할 위치에
임의의 값이 들어가고 level을 다른 순서로 명시해주면 컴파일 에러가 발생 

출력::::
[INFO]인포 로그
[DEBUG]디버그 로그
[WARN]워닝 로그
[ERROR]에러 로그

이 코드를 자바 코드로 변환한다면 아래와 같은 지저분한 코드가 생성이 됩니다.

public void log(String level, String message){
    if (level == null || level.length() == 0){
        level = "INFO";
    }
    if (message == null || message.length() == 0){
        message = "디버그 로그";
    }
       System.out.printf("[%s]%s%n", level, message);
}

    public static void main(String[] args) {
        Logger logger = new Logger();
        logger.log(null ,"인포 로그");
        logger.log("DEBUG" ,null);
        logger.log("WARN" ,"워닝 로그");
        logger.log("ERROR" ,"에러 로그");
    }

코틀린 코드와 자바 코드를 다시 비교 해보자면 아래와 같습니다.

  • 코틀린 코드
fun log(level: String = "INFO", message: String = "디버그 로그"){
    println("[$level]$message")
}
  • 자바 코드
public void log(String level, String message){
    if (level == null || level.length() == 0){
        level = "INFO";
    }
    if (message == null || message.length() == 0){
        message = "디버그 로그";
    }
       System.out.printf("[%s]%s%n", level, message);
}

if...else

코틀린과 자바의 if else는 문법적으로는 정확하게 같습니다.
하지만 코틀린의 경우 if else는 표현식으로 분리가 됩니다.

  • 표현식과 구문
    • 표현식 또는 식 은 그 자체로 값을 만들어 낼 수 있는 문법
    • 구문 또는 문 은 그 자체로 값을 만들지 못함

그래서 자바는 if else'문', 코틀린은 if else '식'으로 분리가 됩니다.
덕분에 kotlin에서는 아래와 같은 코드를 짤 수 있습니다.

val age : Int = 19

val str = if (age > 18) {
  "어른"
} else {
  "아이"
}

println(str)

switch, when

자바에서 switch라는 메서드는 if 문과 비슷하지만 좀 더 정형화된 조건 판단문입니다.
자바에서의 switch문은 break를 실수로 생략하면 원하지 않는 결과가 나옵니다.
물론 의도하여 break를 제거 할 수도 있지만 그렇지 않은 경우 매번 break를 걸어주고 생략 시 사이드이펙트가 발생 할 수 있습니다.
또 자바의 switch'문'은 미리 변수를 초기화 해놓고 결과값을 넣어줘야하므로 비효율적인 코드가 짜여집니다.

  • java의 switch
int day = 2;
String result = "";
switch (day) {
case 1:
result = "월요일"; break;
case 2:
result = "화요일"; break;
case 3:
result = "수요일"; break;
case 4:
result = "목요일"; break;
case 5:
result = "금요일"; break;
case 6:
result = "토요일"; break;
case 7:
result = "일요일"; break;
default:
result = "에러"; break;
}
System.out.println(result);

위와 같은 단점을 보완하여 코틀린에서는 when이라는 메서드를 지원해줍니다.

val day = 2
val result = when (day) {
  1 -> "월요일"
  2 -> "화요일"
  3 -> "수요일"
  4 -> "목요일"
  5 -> "금요일"
  6 -> "토요일"
  7 -> "일요일"
  else -> "에러"
}
println(result)

코틀린의 when 메서드는 else를 생략할 수도 있으며 코틀린이라는 언어를 사용하면서 switch와 when을 선택해서 사용 할 수 있는 것이 큰 매력이라고 봅니다. (break를 의도적으로 사용해야 할 때 switch문 사용)

조건

enum class Color {
  RED, GREEN, BLUE
}

fun getColor() = Color.RED

다른 조건으로 하나의 값이 나와야 할 경우

when (getColor()) {
  Color.RED, Color.GREEN  -> print("color == red or color == green")
  else -> print("blue")
}

else문 생략

when (getColor()) {
  Color.RED -> println("red")
  Color.GREEN -> println("green")
  Color.BLUE -> println("blue")
}

for loop

코틀린에서 for loop는 기본적으로 자바의 foreach와 유사합니다.
범위 연산자 .. 를 사용해 for loop 돌릴수 있습니다.
코틀린은 0..3인 경우 0 < i < 3가 아닌 0 < i <= 3 처럼 동작합니다.

for (i in 0..3) {
  println(i)
}
// 0
// 1
// 2
// 3

만약 0 < i < 3처럼 동작하게 하려면 until을 사용합니다.
until

for (i in 0 until 3) {
  println(i)
}
// 0
// 1
// 2

값을 1씩 증가하는게 아닌 증가 폭을 설정하고 싶으면 step을 사용합니다.
step

for (i in 0..6 step 2) {
  println(i)
}
// 0
// 2
// 4
// 6

값을 감소시키면서 반복시키는 건 downTo를 사용합니다.
downTo

for (i in 3 downTo 1) {
  println(i)
}
// 3
// 2
// 1

받은 배열을 반복문을 통해서 사용하고 싶을 경우

val numbers = arrayOf(1, 2, 3)

for (i in numbers) {
  println(i)
}
// 1
// 2
// 3

출처 : fastcampus

profile
코드를 거의 아트의 경지로 끌어올려서 내가 코드고 코드가 나인 물아일체의 경지

0개의 댓글