코틀린 공식 문서에 있는 Kotlin Tour 를 읽어보고 기본 문법을 정리한다.
1. Hello World
- Hello World
fun main() {
println("Hello, world!")
// Hello, world!
}
"Hello World!" 를 출력하는 간단한 예제이다. 코틀린에서는 함수를 선언할 때 fun 키워드를 사용한다. 자바와 동일하게 main() 함수가 프로그램의 시작점을 의미한다. 문자열 출력은 println() 또는 print() 함수를 통해 수행한다.
- Variables
val popcorn = 5 // There are 5 boxes of popcorn
val hotdog = 7 // There are 7 hotdogs
var customers = 10 // There are 10 customers in the queue
// Some customers leave the queue
customers = 8
println(customers)
// 8
popcorn = 10
// 'val' cannot be reassigned.
코틀린에서 변수를 선언할 때는 val 또는 var 라는 키워드를 사용한다. val 은 자바의 final 과 값이 변하지 않는 변수를 선언할 때, var 는 값이 변할 수 있는 (mutable) 변수를 선언할 때 사용한다. 만약 위의 예제에서 val 로 선언된 popcorn 의 값을 변경하려 한다면 "'val' cannot be reassigned." 라는 메시지와 함께 에러가 발생한다.
- String templates
val customers = 10
println("There are $customers customers")
// There are 10 customers
println("There are ${customers + 1} customers")
// There are 11 customers
println("There are \$${customers + 1} customers")
// There are $11 customers
변수의 값을 문자열로 변환하여 출력하기 위해서는 $ 와 {} 등의 기호를 사용한다. 자바에서는 변수의 타입에 따라 %d, %f 등으로 구분해야 하지만 코틀린에서는 $ 기호만 붙여주면 알아서 변환해준다. 이때 $ 를 키워드가 아닌 그냥 문자로 출력하고 싶으면 마지막 예제와 같이 \ 기호를 앞에 붙여준다.
2. Basic types
모든 변수와 데이터 구조들은 데이터 타입을 가진다. 그런데 이전 예제를 보면 변수를 선언할 때 따로 타입을 선언해주지 않아도 문제없이 실행된다. 코틀린에서는 변수의 타입을 자동으로 추론하는 타입 추론 (type inference) 기능이 있다. 변수에 처음으로 할당되는 값에 따라 변수의 타입을 추론한다.
var customers = 10
// Some customers leave the queue
customers = 8
customers = customers + 3 // Example of addition: 11
customers += 7 // Example of addition: 18
customers -= 3 // Example of subtraction: 15
customers *= 2 // Example of multiplication: 30
customers /= 3 // Example of division: 10
println(customers) // 10
customers = "put string type"
예제와 같이 따로 타입을 정의하지 않아도 초기에 customers 에 입력된 10 에 따라서 숫자 타입으로 인식되어 연산이 가능하다. 만약 마지막 줄 처럼 숫자 타입 변수에 string 과 같이 다른 타입을 입력하면 type mismatch 에러가 발생한다.
코틀린의 데이터 타입은 위의 표와 같다. 만약 변수의 타입을 선언하기 원한다면 아래 예제와 같이 변수 선언 시에 ':' 기호와 함께 타입을 선언해주면 된다.
// Variable declared without initialization
val d: Int
// Variable initialized
d = 3
// Variable explicitly typed and initialized
val e: String = "hello"
// Variables can be read because they have been initialized
println(d) // 3
println(e) // hello
3. Collections
코틀린은 데이터 구조로 Lists, Sets, Maps 를 가지고 있는데, 이들 모두 mutable 또는 read only 로 선언할 수 있다.
- List
리스트는 추가된 순서에 따라 요소들을 저장하며, 중복을 허용한다. 리스트를 생성할 때 read-only 로 (List 타입) 생성하려면 listOf() 함수를 이용하고, mutable 리스트를 (MutableList 타입) 생성하려면 mutableListOf() 함수를 사용한다.
리스트에 저장되는 요소의 타입을 명시적으로 선언하려면 <> 기호를 사용하면 된다. 아래의 예시의 shapes 선언시에 사용된다.
// Read only list
val readOnlyShapes = listOf("triangle", "square", "circle")
println(readOnlyShapes)
// [triangle, square, circle]
// Mutable list with explicit type declaration
val shapes: MutableList<String> = mutableListOf("triangle", "square", "circle")
println(shapes)
// [triangle, square, circle]
println("The first item in the list is: ${readOnlyShapes[0]}")
// The first item in the list is: triangle
println("The first item in the list is: ${readOnlyShapes.first()}")
// The first item in the list is: triangle
println("This list has ${readOnlyShapes.count()} items")
// This list has 3 items
리스트는 요소가 저장된 순서에 따른 인덱스를 가지고 있는데, 인덱스와 [] 기호를 통해서 해당 요소에 접근할 수 있다. 이외에도 first(), last() 함수를 통해서 첫번째, 마지막 요소에 접근할 수 있다. 리스트에 저장된 요소의 전체 개수를 구할 때는 count() 함수를 사용한다.
// Add "pentagon" to the list
shapes.add("pentagon")
println(shapes)
// [triangle, square, circle, pentagon]
// Remove the first "pentagon" from the list
shapes.remove("pentagon")
println(shapes)
// [triangle, square, circle]
리스트에 새로운 값을 추가하거나 삭제해야 하는 경우가 있다. 이때는 add(), remove() 함수를 사용하여 추가, 삭제하면 된다. remove() 로 삭제하려는 요소가 중복되어 리스트에 있는 경우에는 인덱스상 가장 앞에 있는 요소가 삭제된다.
- Set
집합은 요소의 순서가 없고, 중복을 허용하지 않는 데이터 구조이다. read-only (Set) 으로 생성할 때는 setOf(), mutable (MutableSet) 으로 생성할 때는 mutableSetOf() 함수를 사용한다.
// Read-only set
val readOnlyFruit = setOf("apple", "banana", "cherry", "cherry")
// Mutable set with explicit type declaration
val fruit: MutableSet<String> = mutableSetOf("apple", "banana", "cherry", "cherry")
println(readOnlyFruit)
// [apple, banana, cherry]
리스트와 동일하게 add(), remove() 로 요소를 추가할 수 있는데, 만약 중복된 값을 add() 로 수행하면 해당 값은 추가되지 않고 무시된다.
val readOnlyFruit = setOf("apple", "banana", "cherry", "cherry")
println("banana" in readOnlyFruit)
// true
집합이 특정 요소를 포함하고 있는지를 확인하지 위해서는 in 연산자를 사용하면 된다.
- Map
맵은 key-value 형식으로 값을 저장하는 데이터 구조이다. mapOf() 와 mutableMapOf() 함수를 이용하여 각각 read-only (Map) 과 mutable (MutableMap) 한 맵을 생성할 수 있다. 맵을 생성할 때는 아래 예제와 같이 key 와 value 를 to 키워드를 사용하여 매핑하여 생성할 수 있다.
// Read-only map
val readOnlyJuiceMenu = mapOf("apple" to 100, "kiwi" to 190, "orange" to 100)
println(readOnlyJuiceMenu)
// {apple=100, kiwi=190, orange=100}
// Mutable map with explicit type declaration
val juiceMenu: MutableMap<String, Int> = mutableMapOf("apple" to 100, "kiwi" to 190, "orange" to 100)
println(juiceMenu)
// {apple=100, kiwi=190, orange=100}
println("The value of apple juice is: ${readOnlyJuiceMenu["apple"]}")
// The value of apple juice is: 100
맵의 값은 리스트와 같이 [] 연산자로 접근할 수 있는데, 키 값을 인덱스로 하여 접근한다.
juiceMenu.put("coconut", 150) // Add key "coconut" with value 150 to the map
println(juiceMenu)
// {apple=100, kiwi=190, orange=100, coconut=150}
juiceMenu.remove("orange") // Remove key "orange" from the map
println(juiceMenu)
// {apple=100, kiwi=190, coconut=150}
println(juiceMenu.containsKey("kiwi"))
// true
println(juiceMenu.count())
// 3
println(readOnlyJuiceMenu.keys)
// [apple, kiwi, orange]
println(readOnlyJuiceMenu.values)
// [100, 190, 100]
맵에 새로운 값을 입력할 때는 put(key, value) 함수를 사용하여 입력하고 삭제할 때는 remove() 함수로 삭제한다. 특정 키가 맵에 존재하는지 여부를 확인하기 위해서는 containsKey() 함수를 사용한다. keys 와 values 속성을 통해 맵에 저장된 key 와 value 의 목록에 접근할 수 있다.
[Reference]
- https://kotlinlang.org/docs/kotlin-tour-welcome.html
'프로그래밍언어 > Kotlin' 카테고리의 다른 글
[Kotlin] 영역 함수 (Scope functions) (0) | 2024.08.22 |
---|---|
[Kotlin] 튜토리얼 따라가기 (5) (Null safety) (0) | 2024.07.31 |
[Kotlin] 튜토리얼 따라가기 (4) (Classes) (0) | 2024.07.29 |
[Kotlin] 튜토리얼 따라가기 (3) (Functions) (1) | 2024.07.26 |
[Kotlin] 튜토리얼 따라가기 (2) (Control flow) (0) | 2024.07.25 |