프로그래머를 위한 Kotlin 부트캠프 2: Kotlin 기본사항

이 Codelab은 프로그래머를 위한 Kotlin 부트캠프 과정의 일부입니다. Codelab을 순서대로 진행하면 이 과정의 학습 효과를 극대화할 수 있습니다. 기존 지식에 따라 일부 섹션을 훑어볼 수도 있습니다. 이 과정은 객체 지향 언어를 알고 Kotlin을 배우고 싶은 프로그래머를 대상으로 합니다.

소개

이 Codelab에서는 Kotlin 프로그래밍 언어의 기본사항(데이터 유형, 연산자, 변수, 제어 구조, null을 허용하는 변수와 null을 허용하지 않는 변수의 차이점)을 알아봅니다. 이 과정은 객체 지향 언어를 알고 Kotlin을 배우고 싶어 하는 프로그래머를 대상으로 합니다.

이 과정의 강의는 단일 샘플 앱을 빌드하는 대신 지식을 쌓을 수 있도록 설계되었지만, 서로 반독립적이므로 잘 아는 섹션은 대충 훑어볼 수 있습니다. 이러한 요소를 연결하기 위해 많은 예에서 수족관 테마를 사용합니다. 전체 수족관 스토리를 확인하려면 프로그래머를 위한 Kotlin 부트캠프 Udacity 과정을 확인하세요.

기본 요건

  • IntelliJ IDEA에서 프로젝트를 만드는 방법
  • IntelliJ IDEA (Tools > Kotlin > Kotlin REPL)에서 Kotlin의 REPL (Read-Eval-Print Loop)로 코드를 열고 실행하는 방법

학습할 내용

  • Kotlin 데이터 유형, 연산자, 변수를 사용하는 방법
  • 불리언 및 조건 사용 방법
  • null을 허용하는 변수와 null을 허용하지 않는 변수의 차이점
  • Kotlin에서 배열, 목록, 루프가 작동하는 방식

실습할 내용

  • Kotlin REPL을 사용하여 Kotlin 기본사항 학습

이 작업에서는 Kotlin 프로그래밍 언어의 연산자와 유형에 관해 알아봅니다.

1단계: 숫자 연산자 살펴보기

  1. IntelliJ IDEA가 아직 열려 있지 않으면 엽니다.
  2. Kotlin REPL을 열려면 Tools > Kotlin > Kotlin REPL을 선택합니다.

다른 언어와 마찬가지로 Kotlin은 더하기, 빼기, 곱하기, 나누기에 +, -, *, /를 사용합니다. Kotlin은 Int, Long, Double, Float과 같은 다양한 숫자 유형도 지원합니다.

  1. REPL에 다음 표현식을 입력합니다. 결과를 확인하려면 각 항목 후에 Control+Enter (Mac의 경우 Command+Enter)를 누릅니다.
1+1
⇒ res8: kotlin.Int = 2

53-3
⇒ res9: kotlin.Int = 50

50/10
⇒ res10: kotlin.Int = 5

1.0/2.0
⇒ res11: kotlin.Double = 0.5

2.0*3.5
⇒ res12: kotlin.Double = 7.0

연산 결과는 피연산자의 유형을 유지하므로 1/2 = 0이지만 1.0/2.0 = 0.5입니다.

  1. 정수와 십진수의 조합이 다른 표현식을 사용해 보세요.
6*50
⇒ res13: kotlin.Int = 300

6.0*50.0
⇒ res14: kotlin.Double = 300.0

6.0*50
⇒ res15: kotlin.Double = 300.0
  1. 숫자에 대해 몇 가지 메서드를 호출합니다. Kotlin은 숫자를 기본 유형으로 유지하지만 숫자가 객체인 것처럼 숫자에 메서드를 호출할 수 있습니다.
2.times(3)
⇒ res5: kotlin.Int = 6

3.5.plus(4)
⇒ res8: kotlin.Double = 7.5

2.4.div(2)
⇒ res9: kotlin.Double = 1.2

2단계: 유형 사용 연습

Kotlin은 숫자 유형 간에 암시적으로 변환하지 않으므로 short 값을 long 변수에 직접 할당하거나 ByteInt에 할당할 수 없습니다. 이는 암시적 숫자 변환이 프로그램에서 오류의 일반적인 원인이기 때문입니다. 변환을 통해 항상 다른 유형의 값을 할당할 수 있습니다.

  1. 가능한 캐스팅을 확인하려면 REPL에서 Int 유형의 변수를 정의하세요.
val i: Int = 6
  1. 새 변수를 만든 다음 위에 표시된 변수 이름을 입력하고 .to을 입력합니다.
val b1 = i.to

IntelliJ IDEA에 가능한 완성 목록이 표시됩니다. 이 자동 완성은 모든 유형의 변수와 객체에 작동합니다.

  1. 목록에서 toByte()를 선택한 다음 변수를 출력합니다.
val b1 = i.toByte()
println(b1)
⇒ 6
  1. Byte 값을 다양한 유형의 변수에 할당합니다.
val b2: Byte = 1 // OK, literals are checked statically
println(b2)
⇒ 1

val i1: Int = b2
⇒ error: type mismatch: inferred type is Byte but Int was expected

val i2: String = b2
⇒ error: type mismatch: inferred type is Byte but String was expected

val i3: Double = b2
⇒ error: type mismatch: inferred type is Byte but Double was expected
  1. 오류가 반환된 할당의 경우 대신 캐스팅해 보세요.
val i4: Int = b2.toInt() // OK!
println(i4)
⇒ 1

val i5: String = b2.toString()
println(i5)
⇒ 1

val i6: Double = b2.toDouble()
println(i6)
⇒ 1.0
  1. 긴 숫자 상수를 더 쉽게 읽을 수 있도록 Kotlin에서는 적절한 위치에 밑줄을 배치할 수 있습니다. 다른 숫자 상수를 입력해 보세요.
val oneMillion = 1_000_000
val socialSecurityNumber = 999_99_9999L
val hexBytes = 0xFF_EC_DE_5E
val bytes = 0b11010010_01101001_10010100_10010010

3단계: 변수 유형의 값 알아보기

Kotlin은 변경 가능한 유형과 변경 불가능한 유형, 두 가지 유형의 변수를 지원합니다. val을 사용하면 값을 한 번 할당할 수 있습니다. 다시 할당하려고 하면 오류가 발생합니다. var를 사용하면 값을 할당한 다음 나중에 프로그램에서 값을 변경할 수 있습니다.

  1. valvar을 사용하여 변수를 정의한 다음 새 값을 할당합니다.
var fish = 1
fish = 2
val aquarium = 1
aquarium = 2
⇒ error: val cannot be reassigned

fishvar로 정의되어 있으므로 값을 할당한 후 새 값을 할당할 수 있습니다. aquarium에 새 값을 할당하려고 하면 val로 정의되어 있으므로 오류가 발생합니다.

변수에 저장하는 유형은 컴파일러가 컨텍스트에서 파악할 수 있는 경우 추론됩니다. 원하는 경우 콜론 표기법을 사용하여 변수의 유형을 명시적으로 지정할 수 있습니다.

  1. 변수를 정의하고 유형을 명시적으로 지정합니다.
var fish: Int = 12
var lakes: Double = 2.5

유형이 사용자 또는 컴파일러에 의해 할당되면 유형을 변경할 수 없으며 오류가 발생합니다.

4단계: 문자열 알아보기

Kotlin의 문자열은 다른 프로그래밍 언어의 문자열과 거의 동일하게 작동하며, 문자열에는 "을 사용하고 단일 문자에는 '을 사용하며 + 연산자로 문자열을 연결할 수 있습니다. 값과 결합하여 문자열 템플릿을 만들 수 있습니다. $variable 이름은 값을 나타내는 텍스트로 대체됩니다. 이를 변수 삽입이라고 합니다.

  1. 문자열 템플릿을 만듭니다.
val numberOfFish = 5
val numberOfPlants = 12
"I have $numberOfFish fish" + " and $numberOfPlants plants"
⇒ res20: kotlin.String = I have 5 fish and 12 plants
  1. 표현식이 포함된 문자열 템플릿을 만듭니다. 다른 언어와 마찬가지로 값은 표현식의 결과일 수 있습니다. 중괄호 {}를 사용하여 표현식을 정의합니다.
"I have ${numberOfFish + numberOfPlants} fish and plants"
⇒ res21: kotlin.String = I have 17 fish and plants

이 작업에서는 Kotlin 프로그래밍 언어의 불리언과 조건 확인에 대해 알아봅니다. 다른 언어와 마찬가지로 Kotlin에는 불리언과 미만, 같음, 초과 등의 불리언 연산자가 있습니다 (<, ==, >, !=, <=, >=).

  1. if/else 문을 작성합니다.
val numberOfFish = 50
val numberOfPlants = 23
if (numberOfFish > numberOfPlants) {
    println("Good ratio!") 
} else {
    println("Unhealthy ratio")
}
⇒ Good ratio!
  1. if 문에서 범위를 사용해 보세요. Kotlin에서는 테스트하는 조건에 범위를 사용할 수도 있습니다.
val fish = 50
if (fish in 1..100) {
    println(fish)
}
⇒ 50
  1. 여러 케이스가 있는 if를 작성합니다. 더 복잡한 조건의 경우 논리적 and && 및 논리적 or ||을 사용합니다. 다른 언어와 마찬가지로 else if를 사용하여 여러 사례를 만들 수 있습니다.
if (numberOfFish == 0) {
    println("Empty tank")
} else if (numberOfFish < 40) {
    println("Got fish!")
} else {
    println("That's a lot of fish!")
}
⇒ That's a lot of fish!
  1. when 문을 사용해 보세요. Kotlin에서는 다른 언어의 switch 문과 비슷한 when 문을 사용하여 if/else if/else 문을 더 멋지게 작성할 수 있습니다. when 문의 조건에서도 범위를 사용할 수 있습니다.
when (numberOfFish) {
    0  -> println("Empty tank")
    in 1..39 -> println("Got fish!")
    else -> println("That's a lot of fish!")
}
⇒ That's a lot of fish!

이 작업에서는 null을 허용하는 변수와 null을 허용하지 않는 변수에 대해 알아봅니다. null과 관련된 프로그래밍 오류는 수많은 버그의 원인이었습니다. Kotlin은 null을 허용하지 않는 변수를 도입하여 버그를 줄이려고 합니다.

1단계: null 허용 여부 알아보기

기본적으로 변수는 null일 수 없습니다.

  1. Int를 선언하고 null를 할당합니다.
var rocks: Int = null
⇒ error: null can not be a value of a non-null type Int
  1. 변수가 null일 수 있음을 나타내려면 유형 뒤에 물음표 연산자 ?를 사용합니다. Int?를 선언하고 null를 할당합니다.
var marbles: Int? = null

목록과 같은 복잡한 데이터 유형이 있는 경우:

  • 목록의 요소가 null이 되도록 허용할 수 있습니다.
  • 목록이 null이 되도록 허용할 수 있지만 null이 아닌 경우 요소는 null이 될 수 없습니다.
  • 목록과 요소가 모두 null이 되도록 허용할 수 있습니다.

목록과 기타 복잡한 데이터 유형은 나중에 다룹니다.

2단계: ?에 대해 알아보기 및 ?: 연산자

? 연산자를 사용하여 null를 테스트할 수 있으므로 if/else 문을 많이 작성하지 않아도 됩니다.

  1. fishFoodTreats 변수가 null이 아닌지 확인하는 코드를 더 긴 방식으로 작성합니다. 그런 다음 해당 변수를 감소시킵니다.
var fishFoodTreats = 6
if (fishFoodTreats != null) {
    fishFoodTreats = fishFoodTreats.dec()
}
  1. 이제 ? 연산자를 사용하여 Kotlin 방식으로 작성하는 방법을 살펴보겠습니다.
var fishFoodTreats = 6
fishFoodTreats = fishFoodTreats?.dec()
  1. ?: 연산자를 사용하여 null 테스트를 연결할 수도 있습니다. 다음 예를 살펴보세요.
fishFoodTreats = fishFoodTreats?.dec() ?: 0

'fishFoodTreatsnull이 아니면 값을 감소시켜 사용하고, 그렇지 않으면 ?: 뒤의 값인 0을 사용합니다.'의 약어입니다. fishFoodTreatsnull이면 평가가 중지되고 dec() 메서드가 호출되지 않습니다.

null 포인터에 관한 사항

NullPointerExceptions을 정말 좋아한다면 Kotlin에서 유지할 수 있습니다. null이 아님 어설션 연산자 !! (더블뱅)는 모든 값을 null이 아닌 유형으로 변환하고 값이 null이면 예외를 발생시킵니다.

val len = s!!.length   // throws NullPointerException if s is null

이 작업에서는 배열과 목록에 대해 알아보고 Kotlin 프로그래밍 언어에서 루프를 만드는 다양한 방법을 알아봅니다.

1단계: 목록 만들기

목록은 Kotlin의 기본 유형이며 다른 언어의 목록과 유사합니다.

  1. listOf을 사용하여 목록을 선언하고 출력합니다. 이 목록은 변경할 수 없습니다.
val school = listOf("mackerel", "trout", "halibut")
println(school)
⇒ [mackerel, trout, halibut]
  1. mutableListOf를 사용하여 변경할 수 있는 목록을 선언합니다. 항목을 삭제합니다.
val myList = mutableListOf("tuna", "salmon", "shark")
myList.remove("shark")
⇒ res36: kotlin.Boolean = true

remove() 메서드는 전달된 항목을 성공적으로 삭제하면 true을 반환합니다.

2단계: 배열 만들기

다른 언어와 마찬가지로 Kotlin에는 배열이 있습니다. 변경 가능한 버전과 변경 불가능한 버전이 있는 Kotlin의 목록과 달리 Array에는 변경 가능한 버전이 없습니다. 배열을 만들면 크기가 고정됩니다. 새 배열에 복사하는 경우를 제외하고 요소를 추가하거나 삭제할 수 없습니다.

valvar 사용에 관한 규칙은 목록과 배열에서 동일합니다.

  1. arrayOf를 사용하여 문자열 배열을 선언합니다. java.util.Arrays.toString() 배열 유틸리티를 사용하여 출력합니다.
val school = arrayOf("shark", "salmon", "minnow")
println(java.util.Arrays.toString(school))
⇒ [shark, salmon, minnow]
  1. arrayOf로 선언된 배열에는 요소와 연결된 유형이 없으므로 유형을 혼합할 수 있어 유용합니다. 다양한 유형의 배열을 선언합니다.
val mix = arrayOf("fish", 2)
  1. 모든 요소에 대해 하나의 유형으로 배열을 선언할 수도 있습니다. intArrayOf()를 사용하여 정수 배열을 선언합니다. 다른 유형의 배열에는 상응하는 빌더 또는 인스턴스화 함수가 있습니다.
val numbers = intArrayOf(1,2,3)
  1. + 연산자를 사용하여 두 배열을 결합합니다.
val numbers = intArrayOf(1,2,3)
val numbers3 = intArrayOf(4,5,6)
val foo2 = numbers3 + numbers
println(foo2[5])
=> 3
  1. 중첩된 배열과 목록의 다양한 조합을 시도해 보세요. 다른 언어와 마찬가지로 배열과 목록을 중첩할 수 있습니다. 즉, 배열 안에 배열을 넣으면 두 배열의 콘텐츠가 평면화된 배열이 아닌 배열의 배열이 됩니다. 배열의 요소는 목록일 수도 있고 목록의 요소는 배열일 수도 있습니다.
val numbers = intArrayOf(1, 2, 3)
val oceans = listOf("Atlantic", "Pacific")
val oddList = listOf(numbers, oceans, "salmon")
println(oddList)
⇒ [[I@89178b4, [Atlantic, Pacific], salmon]

첫 번째 요소인 numbersArray입니다. 배열 유틸리티를 사용하여 출력하지 않으면 Kotlin은 배열의 콘텐츠 대신 주소를 출력합니다.

  1. Kotlin의 장점 중 하나는 배열을 0으로 초기화하는 대신 코드로 초기화할 수 있다는 것입니다. 다음 예시를 사용해 보세요.
val array = Array (5) { it * 2 }
println(java.util.Arrays.toString(array))
⇒ [0, 2, 4, 6, 8]

초기화 코드는 중괄호 {} 사이에 있습니다. 코드에서 it는 배열 색인을 나타내며 0부터 시작합니다.

3단계: 루프 만들기

이제 목록과 배열이 있으므로 요소를 통해 루프를 실행하면 예상대로 작동합니다.

  1. 배열을 만듭니다. for 루프를 사용하여 배열을 반복하고 요소를 출력합니다.
val school = arrayOf("shark", "salmon", "minnow")
for (element in school) {
    print(element + " ")
}
⇒ shark salmon minnow
  1. Kotlin에서는 요소와 색인을 동시에 반복할 수 있습니다. 다음 예시를 사용해 보세요.
for ((index, element) in school.withIndex()) {
    println("Item at $index is $element\n")
}
⇒ Item at 0 is shark
Item at 1 is salmon
Item at 2 is minnow
  1. 다양한 단계 크기와 범위를 사용해 보세요. 숫자 또는 문자의 범위를 알파벳순으로 지정할 수 있습니다. 다른 언어와 마찬가지로 1씩 증가하지 않아도 됩니다. downTo를 사용하여 뒤로 이동할 수 있습니다.
for (i in 1..5) print(i)
⇒ 12345

for (i in 5 downTo 1) print(i)
⇒ 54321

for (i in 3..6 step 2) print(i)
⇒ 35

for (i in 'd'..'g') print (i)
⇒ defg
  1. 루프를 사용해 보세요. 다른 언어와 마찬가지로 Kotlin에는 while 루프, do...while 루프, ++-- 연산자가 있습니다. Kotlin에는 repeat 루프도 있습니다.
var bubbles = 0
while (bubbles < 50) {
    bubbles++
}
println("$bubbles bubbles in the water\n")

do {
    bubbles--
} while (bubbles > 50)
println("$bubbles bubbles in the water\n")

repeat(2) {
     println("A fish is swimming")
}
⇒ 50 bubbles in the water
49 bubbles in the water
A fish is swimmingA fish is swimming

Kotlin은 연산자, 목록, 루프와 같은 기본 사항에 관해서는 다른 언어와 매우 유사하지만 몇 가지 중요한 차이점이 있습니다.

다음 기능은 Kotlin에서 다른 언어에서 사용하던 것과 다를 수 있습니다.

  • Kotlin 유형은 암시적으로 변환할 수 없습니다. 캐스팅을 사용하세요.
  • val로 선언된 변수는 한 번만 할당할 수 있습니다.
  • Kotlin 변수는 기본적으로 null이 허용되지 않습니다. ?를 사용하여 변수를 null 허용으로 만듭니다.
  • Kotlin을 사용하면 for 루프에서 배열의 색인과 요소를 동시에 반복할 수 있습니다.

다음 Kotlin 프로그래밍 구조는 다른 언어의 구조와 유사합니다.

  • 배열과 목록은 단일 유형 또는 혼합 유형을 가질 수 있습니다.
  • 배열과 목록은 중첩될 수 있습니다.
  • for, while, do/while, repeat로 루프를 만들 수 있습니다.
  • when 문은 Kotlin 버전의 switch 문이지만 when가 더 유연합니다.

Kotlin 문서

이 과정의 주제에 관해 자세히 알아보거나 막히는 부분이 있다면 https://kotlinlang.org에서 시작하는 것이 좋습니다.

Kotlin 튜토리얼

https://try.kotlinlang.org 웹사이트에는 Kotlin Koans라는 풍부한 튜토리얼, 웹 기반 인터프리터, 예시가 포함된 전체 참고 문서 세트가 포함되어 있습니다.

Udacity 과정

이 주제에 관한 Udacity 과정을 보려면 프로그래머를 위한 Kotlin 부트캠프를 참고하세요.

IntelliJ IDEA

IntelliJ IDEA 문서는 JetBrains 웹사이트에서 확인할 수 있습니다.

이 섹션에는 강사가 진행하는 과정의 일부로 이 Codelab을 진행하는 학생에게 출제할 수 있는 과제가 나열되어 있습니다. 다음 작업은 강사가 결정합니다.

  • 필요한 경우 과제를 할당합니다.
  • 과제 제출 방법을 학생에게 알립니다.
  • 과제를 채점합니다.

강사는 이러한 추천을 원하는 만큼 사용할 수 있으며 적절하다고 생각되는 다른 과제를 출제해도 됩니다.

이 Codelab을 직접 진행하는 경우 이러한 과제를 자유롭게 사용하여 배운 내용을 테스트해 보세요.

질문에 답하세요

질문 1

다음 중 변경할 수 없는 문자열 목록을 선언하는 것은 무엇인가요?

val school = arrayOf("shark", "salmon", "minnow")

var school = arrayOf("shark", "salmon", "minnow")

val school = listOf("shark", "salmon", "minnow")

val school = mutableListOf("shark", "salmon", "minnow")

질문 2

다음 코드의 출력은 무엇인가요?
for (i in 3..8 step 2) print(i)

▢ 345678

▢ 468

▢ 38

▢ 357

질문 3

이 코드에서 물음표의 목적은 무엇인가요?
var rocks: Int? = 3

▢ 변수 rocks의 유형이 고정되어 있지 않습니다.

▢ 변수 rocks을 null로 설정할 수 있습니다.

▢ 변수 rocks은 null로 설정할 수 없습니다.

rocks 변수는 즉시 초기화하면 안 됩니다.

다음 강의로 진행합니다. 3. 함수

다른 Codelab 링크를 비롯한 과정 개요는 프로그래머를 위한 Kotlin 부트캠프: 과정에 오신 것을 환영합니다를 참고하세요.