Kotlin/문법

최근 수정 시각: (5년 전)
목차
1. 개요2. 기본3. 편집 지침4. 메인 메서드5. 타입6. 변수 선언
6.1. 특이한 경우: null check6.2. 특이한 경우: 형변환 하기
7. 함수
7.1. 확장 함수
8. 입력 받기
8.1. Bufferreader8.2. Scanner
9. 출력하기
9.1. 문자9.2. 숫자
10. 배열
10.1. Array10.2. List
11. 반복문
11.1. for문11.2. while문
12. 제어문
12.1. if[else]12.2. when
13. 상속14. 람다식
14.1. 고차함수

1. 개요 [편집]

Kotlin(코틀린)의 문법을 설명하는 문서다.

2. 기본 [편집]

코틀린의 코드는 객체 지향을 원칙으로 하며, 자바100% 연계되는 문법을 사용하고 있다.[1]

.kt 또는 .kts의 저장 형식을 가진다. 위에서도 서술 했듯이 자바와 굉장히 비슷한 문법 구조를 가지고 있어 자바를 한번 배워 본 사람이라면 코틀린을 어렵지 않게 배울 수 있다. 또한 코드가 매우 간결하여 쉽게 배울 수 있다. 그럼에도 불구하고 안드로이드 앱을 만들 때도 기능상의 제한이 없다. 함수 선언 방법 또한 자바와 동일하다.

3. 편집 지침 [편집]

소스 코드로 예시를 들 때
{{{#!syntax java (소스코드) }}}
문법을 활용하여 소스코드를 써 주시기 바랍니다.
코틀린 전용은 지원하지 않습니다.

또한 메인함수에는 통일을 위해 array 대신 args를 사용하시기 바랍니다.

예시:
package HelloWorld;

 fun main(args: Array<String>) {
     println("Hello world!")
 }

4. 메인 메서드 [편집]

package HelloWorld;

 fun main(args: Array<String>) {
     // TODO
 }

코틀린의 경우에는 메인메서드의 길이가 상당히 짧다. C언어, 자바등과 비교하면 짧다는거지 메인함수가 없는 파이썬과 비교하면 곤란하다. 당장 패키지명만 선언하고 메인함수를 작성한 뒤 바로 코딩에 들어가도 무방하다. argsarray 둘 다 사용법은 같다. 똑같이 작동하지만 JDK 환경인지, Native로 작동하는지 등에 따라서 다르다.

Kotlin 1.3 버전부터는 args를 붙일 필요는 없게 됐다.

5. 타입 [편집]

  • 숫자(정수): Long[2] > Int[3] > Short[4] > Byte [5]
  • 숫자(실수): Double[6] > Float[7]
  • 문자: Char[8]
  • 문자열: String[9]

6. 변수 선언 [편집]

package HelloWorld;

 fun main(args: Array<String>) {
     var a1: Int = 1
     var a2 = 1
     var b: String = "1"
     val c: Double = 3.141592

     println(a1) // OK
     println(b) // OK
     println(c) // OK

    a1 = a1 ++ // OK
    b = b + "2" // OK
    c = c ++ // ERROR

 }

타입을 적어줘도, 적어주지 않아도 된다. var이 아니라 val로 쓰게 된다면 c = c ++과 같이 그 값을 바꾸지 못한다. 기본적으로는 val을 쓰는게 좋은 습관이지만, 어차피 대부분 var로 바꿀거 var로 코딩 하는 사람도 적지 않다.

6.1. 특이한 경우: null check [편집]

package HelloWorld;

 fun main(args: Array<String>) {
     var a: Int? = 1
     var b: Int? = 1

     println(a !! + b !!)

     var c: Int? = null // OK
     var d: Int = null // ERROR

 }
기본적으로 ?를 타입 뒤에 붙이면 null을 사용할 수 있다. 하지만 둘 다 null 선언이 된 상태에서 값을 수정하거나 출력하려 하면 null check 에러가 뜨는 경우가 있다. 이런 경우에는 !!를 붙여주면 해결되는 경우도 있다.

6.2. 특이한 경우: 형변환 하기 [편집]

package HelloWorld;

 fun main(args: Array<String>) {
     var a: Int = 1
     var b: String = 1

     println(a + b) // ERROR
     println(a + b.toInt()) // OK

     var c: Int = 1
     var d: String = 1

     println(c + d!!.toInt()) // OK

 }

String과 Int를 더하려면 오류가 나기 때문에 .to타입()을 붙여 타입을 변경할 수 있다. null check를 하는 경우 d!!.toInt()로 해주면 된다.

7. 함수 [편집]

package HelloWorld;

 fun main(args: Array<String>) {
     // TODO

     var Method: Method = Method
     Method.Method1() // ERROR
     Method.Method2() // OK
 }
 class Method() {

     fun Method1() {
       println("Hello")
    }
     open fun Method2() {
         println("Hello")
     }
 }

함수를 쓸 때 앞에 open을 붙여줘야 다른 곳에서도 똑같이 사용할 수 있다. open을 붙이지 않는다면 val같이 읽기 전용으로만 이용 할 수가 있다. 함수에 대한 기본개념이 있다면 어떻게 사용하는지 문법만 배우면 된다. Method1과 Method2를 class Method로 감싸줬는데 이를 사용하기 위해서는 var Method: Method = Method로 그것을 쓸 함수에 선언을 해주어야한다. 참고로 Method라는 클래스의 타입은 그대로 Method가 된다.

계속 Method라는 얘기가 나오는데 클래스의 이름을 Method로 할 필요는 없다. 어떤 컴파일러에서는 함수명으로 한글도 지원된다.

7.1. 확장 함수 [편집]

이미 선언되어있는 객체나 클래스 하위의 함수를 재정의하거나 새로 정의할 수도 있다.

package HelloWorld

fun String.sayHello() {
    println("Hello, $this") // this는 객체 String을 가리킴
}

fun main(args: Array<String>) {
    "NamuWiki".sayHello() // "Hello, NamuWiki" 출력
}

8. 입력 받기 [편집]

8.1. Bufferreader [편집]

8.2. Scanner [편집]

9. 출력하기 [편집]

9.1. 문자 [편집]


package HelloWorld;

 fun main(args: Array<String>) {
     // 1
     print("안녕")
     println("하세요")
     // 2
     var Hello: String = "안녕하세요"
     println(Hello)
     // 3
     // 4
     var World1 : String = "안녕"
     var World2 : String = "하세요"
     println("${World1 + World2}")
     println(World1 + World2)
 }

네가지 경우 모두 안녕하세요가 출력된다. print인 경우는 줄바꿈을 하지 않는다. C언어를 예로 들자면 printf("hello world!\n"); 에서 \n이 생략된 격이다. 이 말은 즉슨 println의 경우에는 \n이 자동으로 삽입되어 있다는 뜻이다. \n = ln ? 물론 \n 사용이 불가능 한 것은 아니다. 다만 println이 쓰이는데 \n까지 같이 쓴다면 두줄 줄 바꿈이 된다.

9.2. 숫자 [편집]

10. 배열 [편집]

10.1. Array [편집]

Array를 만들 때는 이와 같이 하면 된다
package HelloWorld;

fun main(args: Array<String>) {
    val doubleArray: Array<Double> = arrayOf(1.0, 1.5, 2.0, 3.0)
}


위의 경우 arrayOf 안에 있는 값을 가져가서 Array가 그 값들의 type을 가지게 된다.

10.2. List [편집]

11. 반복문 [편집]

11.1. for문 [편집]

package HelloWorld

fun main (args: Array<String>) {
    for (i in 0 .. 5) {
        println("안녕하세요")
    }
    for (i in 1 .. 6) {
        println("안녕하세요")
    }
    for (i in 1 until break) {
        println("안녕하세요")
    } 
}

첫번째와 두번째 경우 둘 다 안녕하세요가 5번 출력된다. 반쯤 람다식이라고 볼 수 있는데, 기존 Java와 절차지향 언어인 C언어에서 쓰였던 var i = 0; i > 10; i ++ 같은 문법 대신 눈물나게 간결한 문법을 제공한다.

세번째 경우인 until의 경우에는 저 자체로는 굉장히 불완전한 코드이다. until을 이용해서 break까지, 변수 a의 값이 5가 될때 까지등 여러가지 조건을 내걸어 반복문을 사용 할 수 있다.

이중 반복문을 사용하려는 경우 첫번째 반복문에 변수로 i를 지정해주었다면 두번째 반복문에는 i를 사용하면 안된다. 코드 안에서 내부적으로 i를 여러번 반복하고 그 반복 안에 새로운 i가 있는 형식이기 때문이다. 여러 IDE에서 실행을 해보면 빨간색 밑줄 또는 노란색 밑줄이 그어지면서 this variable is alreadt defined같은 오류가 뜬다.

11.2. while문 [편집]

12. 제어문 [편집]

12.1. if[else] [편집]

if (expression) statement1 [else statement2]

() 속의 조건식(expression)이 참이 되면 statement1을, 거짓이면 statement2를 실행하는 구조로 되어 있다. else 이하는 생략 가능하며 else 뒤에 if를 다시 사용하여 if ... else if ... else if ... else 와 같이 사용할 수도 있다.

package HelloWorld;

fun main(args: Array<String>) {
    var a = 1
    var b = 1
    if(a == b) {
        // TODO
    } else {
        // TODO
    }
}

12.2. when [편집]

자바switch 문이랑 비슷하지만 더 많은 기능을 가졌다.

package HelloWorld;

fun main(args: Array<String>) {
    var a = 1

    when(a) {
        1 -> println("a는 1입니다")
        5 -> println("a는 5입니다")
        7, 9 -> println("a는 7 아니면 9입니다")
        in 10..100 -> println("a는 10에서 100까지 중에 있습니다")
        else -> println("a는 그 외입니다")
    }

}

13. 상속 [편집]

한 객체가 다른 객체를 상속할 때에는 다음과 같은 형태를 띈다.
package kotlin

class ParentClass()

class ChildClass: ParentClass()


한 객체가 인터페이스를 구현할 때에는 다음과 같은 형태를 띈다.
package kotlin

interface SampleInterface()

class ChildClass: SampleInterface


14. 람다식 [편집]

14.1. 고차함수 [편집]

코틀린은 인터페이스를 통해서 함수를 인자로 넘겨주던 Java와 다르게 아주 간편하게 함수를 주고받거나 반환할 수 있다.
  • 함수를 인자로 받기
    package Kotlin
        
    fun printer(a: Int, b: Int, f: (Int, Int) -> Int) {
        println("$a 와 $b 를 함수에 -> ${f(a, b)}")
    }
  • 함수를 반환하기
    package Kotlin
    
    fun getPrintingFunction(str: String): () -> Unit {
        return { println(str) }
    }

또한, 함수(람다식)을 인자로 넘겨주는 함수를 사용할 경우, 함수의 내용을 소괄호 밖에 표시하는것이 권장된다.

printer(3, 5, {i, j -> i + j}) // 작동
printer(3, 5) {i, j ->
    i + j
} // 작동


이와 앞서 언급한 클래스 내 함수 삽입을 이용하면 context를 만들 수 있다.

package HelloWorld;

object NamuWiki {
    fun getDocument(name: String): String {
        // TODO
    }
}

fun <T> namuWiki(lambda: NamuWiki.() -> T) : T { // lambda는 Namuwiki 하위 함수
    return NamuWiki.lambda()
}

fun main(args: Array<String>) {
    val kotlin: String = namuWiki { // returns result of getDocuent()
        getDocument("Kotlin/문법") // getDocument under context namuWiki
    }

    getDocument("Kotlin/문법") // ERROR: function getDocument doesn't exist

    println(kotlin)
}
[1] 실제로 안드로이드 스튜디오 등에서 자바 코드를 넣으면 자동으로 코틀린으로 변환해 준다.[2] Int보다 큰 수 입출력 가능[3] 8자리까지 입출력 가능[4] Int보다 작은 수 입출력 가능[5] Short보다 작은 수 입출력 가능[6] 나눗셈등을 할때 요긴하게 사용된다.[7] 많이 쓰지는 않는다.[8] 한 글자 입출력 가능[9] 문자열 입력에 제한이 없다.

라이선스를 별도로 명시하지 않은 문서는 CC BY-NC-SA 2.0 KR에 따라 이용할 수 있습니다.
기여하신 문서의 저작권은 각 기여자에게 있으며, 각 기여자는 기여하신 부분의 저작권을 갖습니다.

문서의 기여자는 역사 탭에서 확인할 수 있습니다.
접두어의 N: - 나무위키 사용자, R: - 리그베다 위키의 사용자를 뜻합니다.
자세한 사항은 나무위키에서 동일한 문서의 역사를 참고하시기 바랍니다.