[Kotlin] Kotlin의 기본 문법

·2024년 2월 5일

Kotlin 기본 문법

2.1 변수와 데이터 형식

  • Kotlin의 변수 선언 방식

    ① 암시적 선언 : 변수의 데이터 형식을 지정하지 않고, 대입되는 값에 따라 자동으로 변수의 데이터 형식이 지정

    var var1 = 10              // var var1 : Int = 10
    var var2 = 10.1f           // var var2 : Float = 10.1f
    var var3 = 10.2            // var var3 : Double = 10.2
    var var4 = '안'            // var var4 : Char = '안'
    var var5 = "안드로이드"    // var var5 : String = "안드로이드"
    • 단, 초기화하지 않는 경우에는 데이터 형식을 반드시 명시
      var var1 : Int
      var var2 : Float
      var var3 : Double
      var var4 : Char
      var var5 : String

    ② var(variable)

    • 일반 변수를 선언할 때 사용
    • 필요할 때마다 계속 다른 값을 대입 가능
      var myVar : Int = 100
      myVar = 200  // 정상

    ③ val(value)

    • 변수 선언과 동시에 값을 대입하거나, 초기화 없이 선언한 후에 한 번만 값을 대입 가능
    • 한 번 값을 대입하고 나면 값 변경 불가
      val myVal : Int = 100
      myVal = 200  // 오류
  • 데이터 형식 변환

    • 캐스팅 연산자 사용
    • Kotlin에서 제공하는 toInt( )나 toDouble( ) 등의 정적 메소드 사용
      var a : Int = "100".toInt()
      var b : Double = :100.123".toDouble()
  • null 사용

    • Kotlin은 기본적으로 변수에 null 값을 넣지 못함
      • 변수를 선언할 때 데이터 형식 뒤에 ?를 붙여야 null 대입 가능
      var notNull : Int = null  // 오류
      var okNull : Int? = null  // 정상
  • 변수가 null 값이 아님을 표시해야 하는 경우

    • !!로 나타냄
      • 이 경우 null 값이 들어가면 오류 발생
      var ary = ArrayList<Int>(1)  // 1개짜리 배열 리스트
      ary!!.add(100)  // 값 100을 추가

2.2 조건문: if, when

  • if문
    • 조건이 true인지 false인지에 따라서 어떤 작업을 할 것인지를 결정
    • = 이중 분기
    if (조건식) {
      // 조건식이 true일 때 이 부분 실행
    }
    if (조건식) {
      // 조건식이 true일 때 이 부분 실행
    } else {
      // 조건식이 false일 때 이 부분 실행
    }
  • when문
    • 여러 가지 경우에 따라서 어떤 작업을 할 것인지를 결정
    • = 다중 분기
      when () {-> // 값1이면 이 부분 실행-> // 값2이면 이 부분 실행else -> // 어디에도 해당하지 않으면 이 부분 실행
      }

▶️💻예) count변수에 저장된 값에 따라서 A학점 ~ F학점 출력

fun main() {
    var count: Int = 85

    // if-else
    if (count >= 90) {
        println("A학점")
    } else if (count >= 80) {
        println("B학점")
    } else if (count >= 70) {
        println("C학점")
    } else if (count >= 60) {
        println("D학점")
    } else {
        println("F학점")
    }

    // when                               //  var count: Int = (count / 10) * 10
    when(count) {                         //  when (count) {
        in 90 .. 100 -> println("A학점")  //        100, 90 -> println("A학점")
        in 80 .. 89 -> println("B학점")   //        80 -> println("B학점")
        in 70 .. 79 -> println("C학점")   //        70 -> println("C학점")
        in 60 .. 69 -> println("D학점")   //        60 -> println("D학점")
        else -> println("F학점")          //        else -> println("F학점")
    }                                     // }
}

2.3.1 배열

  • 배열 : 여러 개의 데이터를 하나의 변수에 저장하기 위해 사용

  • 일차원 배열 선언 형식: Array(), arrayOf(), arrayOfNullls()

    • Array()
      var 배열명 = Array<데이터 형식>(개수, {초깃값})
      var 배열명 = Array<데이터 형식>(개수) {초깃값}
      • 일차원 배열(one[4])을 선언하고 값을 대입하는 방법
        var one = Array<Int>(4, {0})
        one[0] = 10
        one[1] = 20
    • arrayOf()
      val numbers = arrayOf(4, 5, 7, 3)  // 정수형으로 초기화된 배열
      val animals = arrayOf("Cat", "Dog", "Lion")  // 문자열형으로 초기화된 배열
    • arrayOfNullls()는 빈배열로 선언
  • 이차원 배열 선언 형식

    var 배열명 = Array<배열 데이터 형식>(행 개수, {배열 데이터 형식(열 개수)})
    • 3×4 이차원 배열(two[3][4])을 선언하고 값을 대입하는 방법

      var two = Array<IntArray>(3, {IntArray(4)})
      two[0][0] = 100
      two[2][3] = 200
    • 3x3 이차원 배열(arr2d[3][3]) 선언 방법

      val array1 = arrayOf(1, 2, 3)
      val array2 = arrayOf(4, 5, 6)
      val array3 = arrayOf(7, 8, 9)
      
      val arr2d = arrayOf(array1, array2, array3)
      val arr2d = arrayOf(arrayOf(1, 2, 3), arrayOf(4, 5, 6), arrayOf(7, 8, 9))
  • 배열을 선언하면서 값을 바로 대입하는 것도 가능

    var three: IntArray = intArrayOf(1, 2, 3)
  • ArrayList

    var one = ArrayList<Int>(4)
    one.add(10)
    one.add(20)
    var hap = one.get(0) +one.get(1)  // 첫 번째 값 + 두 번째 값

2.3.2 반복문: for, while

  • for문
    for (변수 in 시작..끝 step 증가량) {
        // 이 부분을 반복 실행
    }
    • 배열의 개수만큼 변수에 대입하여 반복하는 방법
      for (변수 in 배열명.indices) {
          // 이 부분을 반복 실행
      }
    • 배열의 모든 값을 출력하는 방법
      var one : IntArray = intArrayOf(10, 20, 30, 40)
      for (i in one.indices) {
          println(one[i])
      }
    • 첨자(i) 없이 바로 배열의 값을 하나씩 처리하는 방법
      • 배열의 내용이 하나씩 변수에 대입된 후 for문 내부 실행 → 결국 배열의 개수만큼 for 문이 반복됨
      for (변수 in 배열명) {
          // 이 부분에서 변수 사용
      }
  • while문
    while (조건식) {
        // 조건식이 true인 동안 이 부분을 실행
    }
    • break vs continue
      break: 무조건 반복문 밖으로 탈출
      continue: 무조건 끝으로 건너뛴 후 다시 반복문으로 돌아감

▶️💻예) sum변수에 1~10까지 더하고 출력

// for
fun main() {
    var sum = 0

    for (x in 1..10) {
        sum += x  //sum = sum +x
    }
    println("sum: $sum")

    sum = 0

    for (x in 1..10 step 1) sum += x
    println("sum= $sum")
}
// while
fun main() {
    var sum = 0
    var x = 0

    while (x <= 10) {
        sum += x
        x++
    }
    println("sum: $sum")

    sum = 0
    x = 0
    do {
        sum += x
        x++
    } while (x <= 10)
    println("sum: $sum")

}

▶️💻예) 배열의 모든 원소 출력

fun main() {
    var one: IntArray = intArrayOf(10, 20, 30)
    for (i in one.indices) {
        println(one[i])
    }
    for (value in one) {
        println(value)
    }

    var two: Array<String> = arrayOf("하나", "둘", "셋")
    for (i in 0..2 step 1) {
        println(two[i])
    }
    var k: Int = 0
    while (k < two.size) {
        println(two[k])
        k++
    }
}

▶️💻예) 3X3 크기의 이차원 배열 선언하고 for문 이용하여 값 할당

fun main() {
    var two = Array<IntArray>(3, { IntArray(3) })
    //var three = arrayOf(arrayOf(100, 110, 120), arrayOf(130, 140, 150), arrayOf(160, 170, 180))

    var value: Int = 100
    for (i in 0..2) {
        for (j in 0..2) {
            two[i][j] = value
            value = value + 10
            println("two[$i][$j]: ${two[i][j]}")
        }
    }
}

▶️💻예) 5단부터 8단까지 구구단을 출력 (for문)

fun main() {
    for (i in 5..8) {
        for (j in 1..9)
            println("$i X $j = ${i * j}")
        println("*************")
    }
}

▶️💻예) 1부터 100사이의 홀수를 누적(while문, for문)

fun main() {
	// while
    var sum = 0
    var i = 0
	
    while (i <= 100) {
        if (i % 2 != 0)
            sum += i
        i++
    }
    println("sum(while) = $sum")

	// for
    sum = 0
    i = 0
    for (i in 1.. 100 step 2) {
        sum += i
    }
    println("sum(for) = $sum")
}

2.4 함수

  • 함수의 선언

    fun 함수 이름([변수 이름: 자료형, 변수 이름: 자료형…]): [반환 값 자료형] {
        표현식…
        [return 반환값]
    }
    // ex)
    fun sum(a: Int, b: Int): Int {
        var sum = a + b
        return sum
    }
  • 코틀린은 다중 패러다임 언어

    • 함수형 프로그래밍(FP: Functional Programming)
    • 객체 지향 프로그래밍(OOP: Object-Oriented Programming)
  • 함수형 프로그래밍

    • 코드 간략, 테스트나 재사용성 증가
    • 순수 함수, 람다식, 고차 함수를 사용해 구성
  • 일반적 선언

    fun sum(a: Int, b: Int): Int {
      return a + b
    }
  • 간략한 선언

    fun sum(a: Int, b: Int): Int = a + b
    fun sum(a: Int, b: Int) = a + b

▶️💻 sumFunc.kt

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

fun main() {
    val result1: Int
    val result2: Int

    result1 = sum(3, 2)
    result2 = sum(6, 7)

    println(result1)
    println(result2)
}

▶️💻 maxFunc.kt

fun main() {
    val num1 = 10
    val num2 = 3
    val result: Int
    result = max(num1, num2)
    println(result)
}

fun max(a: Int, b: Int) = if (a > b) a else b

▶️💻 두 개의 숫자를 입력 받아서 덧셈, 뺄셈, 곱셈을 함수를 이용해 출력

  • 키보드 입력 : readline()
  • 정수형 변환 : readline()!!.toInt()
fun add(a:Int, b:Int) = a+b
fun sub(a: Int, b: Int): Int = a - b
fun mul(a: Int, b: Int): Int {
    return a * b
}

fun main() {
    var num1: Int
    var num2: Int

    print("number1 = ")
    num1 = readLine()!!.toInt()
    print("number2 = ")
    num2 = readLine()!!.toInt()

    println("number1 + number2 = ${add(num1, num2)}")
    println("number1 - number2 = ${sub(num1, num2)}")
    println("number1 * number2 = ${mul(num1, num2)}")
}

  • 순수함수 (pure function)

    • 부작용이 없는 함수
    • 동일한 입력 인자에 대해서는 항상 같은 결과를 출력 혹은 반환
    • 값이 예측이 가능해 결정적
      // 순수 함수의 예
      fun sum(a: Int, b: Int): Int {
      return a + b // 동일한 인자인 a, b를 입력 받아 항상 a + b를 출력(부작용이 없음)
      }
    • 순수 함수의 조건
      • 같은 인자에 대하여 항상 같은 값을 반환
      • 함수 외부의 어떤 상태도 바꾸지 않음
  • 람다식(Lambda Expression)

    • 익명 함수의 하나의 형태로 이름 없이 사용 및 실행이 가능
      { x, y -> x + y } // 람다식의 예 (이름이 없는 함수 형태)
    • 람다식의 이용
      • 람다식은 고차 함수에서 인자로 넘기거나 결과값으로 반환 등을 할 수 있음
      • 변수에 람다식 적용
        fun main() {
          var result: Int
          val multi = {x: Int, y: Int -> x * y}  // 일반 변수에 람다식 할당
          result = multi(10, 20)  // 람다식이 할당된 변수는 함수처럼 사용 가능
          println(result)
        }
    • 람다식의 표현
      • 파라미터 2개를 받아서 합계를 출력하는 일반적인 메소드 형식
        fun addNumber (n1: Int, n2: Int): Int {
          return n1 + n2
        }
      • 이를 람다식으로 간단히 표현
        val addNumber = { n1: Int, n2: Int -> n1 + n2 }
    • 람다식의 특징
      • 람다식은 { }로 감싸며 fun 예약어를 사용 X
      • { } 안 ->의 왼쪽은 파라미터, 오른쪽은 함수의 내용
      • -> 오른쪽 문장이 여러 개라면 세미콜론(;)으로 구분
      • 내용 중 마지막 문장은 반환 값(return)임
      • ex) 버튼을 클릭했을 때 실행되는 람다식을 아래 형태로 구현함
        버튼변수.setOnClickListener {
          // 버튼을 클릭하면 실행될 내용
        }
  • 고차 함수(high-order function)

    • 일반 함수를 인자나 반환값으로 사용
      fun main() {
        println(highFunc({ x, y -> x + y }, 10, 20))  // 람다식 함수를 인자로 넘김
      }
      fun highFunc(sum: (Int, Int) -> Int, a: Int, b: Int): Int = sum(a, b)  // sum 매개변수는 함수

profile
깡통 채우기

0개의 댓글