코틀린 기본 문법에 대해 정리한 글입니다. 코틀린의 기본 문법들의 개요 정도로 정리되어 있으며 자세한 내용은 별도로 더 알아봐야합니다.
패키지 정의와 불러오기
package my.demo
import kotlin.text.*
// ...
소스 파일은 패키지 디렉토리와 일치할 필요는 없습니다. 프로젝트 내부에 임의에 곳에 있으면 됩니다.
프로그램 시작점
fun main() {
println("Hello world!")
}
어플리케이션의 시작점은 main 함수 입니다.
어플리케이션 시작 시 인자를 전달하고 싶다면 다음과 같이 작성할 수 있습니다:
fun main(args: Array<String>) {
println(args.contentToString())
}
표준 출력으로 인쇄하기
`print` 는 표준 출력으로 인자값을 인쇄합니다:
fun main() {
print("Hello ")
print("world!")
}
--------------------------
Hello world!
`println` 은 인자값 뒤에 개행 문자를 더하여 인쇄합니다.
fun main() {
println("Hello world!")
println(42)
}
--------------------------------
Hello world!
42
표준 입력으로부터 읽기
`readIn()` 함수는 표준 입력으로부터 읽습니다. 이 함수는 사용자가 엔터를 친 모든 줄을 읽습니다.
// Prints a message to request input
println("Enter any word: ")
// Reads and stores the user input. For example: Happiness
val yourWord = readln()
// Prints a message with the input
print("You entered the word: ")
print(yourWord)
// You entered the word: Happiness
함수
두개의 Int 인자를 받고 Int 형을 응답하는 함수:
fun sum(a: Int, b: Int): Int {
return a + b
}
fun main() {
print("sum of 3 and 5 is ")
println(sum(3, 5))
}
----------------------------------
sum of 3 and 5 is 8
함수 내용을 표현식으로 사용할 수 있습니다. 이 때 응답 형식은 추론됩니다:
fun sum(a: Int, b: Int) = a + b
fun main() {
println("sum of 19 and 23 is ${sum(19, 23)}")
}
----------------------------------------------------
sum of 19 and 23 is 42
이 함수는 의미없는 값을 응답합니다:
fun printSum(a: Int, b: Int): Unit {
println("sum of $a and $b is ${a + b}")
}
fun main() {
printSum(-1, 8)
}
--------------------------------------------
sum of -1 and 8 is 7
Unit 응답 형식은 생략될 수 있습니다:
fun printSum(a: Int, b: Int) {
println("sum of $a and $b is ${a + b}")
}
fun main() {
printSum(-1, 8)
}
---------------------------------------------
sum of -1 and 8 is 7
변수
코틀린에서 변수 이름 앞에 `val` 또는 `var` 을 선언합니다.
`val` 은 선언하면 값에 단 한번만 값을 할당할 수 있고, 더 이상 변조되지 않습니다. 초기화 후에 다른 값으로 재할당할 수 없는 읽기 전용 지역 변수입니다:
fun main() {
// Declares the variable x and initializes it with the value of 5
val x: Int = 5
// 5
println(x)
}
-----------------------------------------
5
`var` 은 재할당 가능한 변수를 선언합니다. 변조가 가능하고 초기화 후에 다른 값으로 변경할 수 있어요:
fun main() {
// Declares the variable x and initializes it with the value of 5
var x: Int = 5
// Reassigns a new value of 6 to the variable x
x += 1
// 6
println(x)
}
-----------------------------------
6
Kotlin 은 type 추론을 지원하고 선언된 변수의 자료형을 자동으로 식별합니다. 변수를 선언할 때 변수 이름 뒤에 자료형을 생략할 수 있어요:
fun main() {
// Declares the variable x with the value of 5;`Int` type is inferred
val x = 5
// 5
println(x)
}
--------------------------------
5
변수는 초기화한 후에만 사용이 가능합니다. 선언할 때 초기화하거나 변수만 선언하고 나중에 초기화할 수 있습니다. 후자의 경우엔 변수 이름 뒤에 자료형을 반드시 지정해야합니다:
fun main() {
// Initializes the variable x at the moment of declaration; type is not required
val x = 5
// Declares the variable c without initialization; type is required
val c: Int
// Initializes the variable c after declaration
c = 3
// 5
// 3
println(x)
println(c)
}
--------------------------------------
5
3
그리고 최상위 level (메인 함수 밖) 에서도 변수를 선언할 수 있어요:
val PI = 3.14
var x = 0
fun incrementX() {
x += 1
}
// x = 0; PI = 3.14
// incrementX()
// x = 1; PI = 3.14
fun main() {
println("x = $x; PI = $PI")
incrementX()
println("incrementX()")
println("x = $x; PI = $PI")
}
----------------------------------
x = 0; PI = 3.14
incrementX()
x = 1; PI = 3.14
Class 와 Instance 만들기
class 정의해보죠:
class Shape
클래스 속성들은 클래스 선언부나 본문에 나열할 수 있어요:
class Rectangle(val height: Double, val length: Double) {
val perimeter = (height + length) * 2
}
기본 생성자는 인자들과 클래스 정의에서 자동으로 만들어집니다. 별도로 작성할 필요가 없습니다.
class Rectangle(val height: Double, val length: Double) {
val perimeter = (height + length) * 2
}
fun main() {
val rectangle = Rectangle(5.0, 2.0)
println("The perimeter is ${rectangle.perimeter}")
}
----------------------------------------------------------
The perimeter is 14.0
클래스간에 상속은 `:` 으로 선언할 수 있습니다. 클래스는 기본적으로 `final` 입니다. 상속되는 대상은 `open` 으로 선언해줘야합니다.
open class Shape
class Rectangle(val height: Double, val length: Double): Shape() {
val perimeter = (height + length) * 2
}
주석
대부분의 최인 언어들처럼 코틀린은 한줄 또는 여러줄 주석을 지원합니다
// This is an end-of-line comment
/* This is a block comment
on multiple lines. */
코틀린 주석 덩어리는 중첩 될 수 있습니다
/* The comment starts here
/* contains a nested comment */
and ends here. */
문자열 템플릿
fun main() {
var a = 1
// simple name in template:
val s1 = "a is $a"
a = 2
// arbitrary expression in template:
val s2 = "${s1.replace("is", "was")}, but now is $a"
println(s2)
}
---------------------------------------------------------
a was 1, but now is 2
문자열 내에서 수식을 평가할 수 있습니다. 평가를 위해선 `${}` 중괄호를 사용해야합니다. 또 단순 문자열 치환은 중괄호가 필요없습니다.
조건부 표현식
fun maxOf(a: Int, b: Int): Int {
if (a > b) {
return a
} else {
return b
}
}
fun main() {
println("max of 0 and 42 is ${maxOf(0, 42)}")
}
--------------------------------------------------
max of 0 and 42 is 42
코틀린에서, `if` 는 표현식 처럼 사용할 수 있습니다
fun maxOf(a: Int, b: Int) = if (a > b) a else b
fun main() {
println("max of 0 and 42 is ${maxOf(0, 42)}")
}
-----------------------------------------------------
max of 0 and 42 is 42
for 반복문
fun main() {
val items = listOf("apple", "banana", "kiwifruit")
for (item in items) {
println(item)
}
}
--------------------------------------------------------
apple
banana
kiwifruit
또는
fun main() {
val items = listOf("apple", "banana", "kiwifruit")
for (index in items.indices) {
println("item at $index is ${items[index]}")
}
}
----------------------------------------------------
item at 0 is apple
item at 1 is banana
item at 2 is kiwifruit
while 반복문
fun main() {
val items = listOf("apple", "banana", "kiwifruit")
var index = 0
while (index < items.size) {
println("item at $index is ${items[index]}")
index++
}
}
-----------------------------------------------------------
item at 0 is apple
item at 1 is banana
item at 2 is kiwifruit
when 표현식
fun describe(obj: Any): String =
when (obj) {
1 -> "One"
"Hello" -> "Greeting"
is Long -> "Long"
!is String -> "Not a string"
else -> "Unknown"
}
fun main() {
println(describe(1))
println(describe("Hello"))
println(describe(1000L))
println(describe(2))
println(describe("other"))
}
--------------------------------------------
One
Greeting
Long
Not a string
Unknown
Ranges
range 내에 숫자들이 있다면 `if` 를 통해서 확인할 수 있습니다
fun main() {
val x = 10
val y = 9
if (x in 1..y+1) {
println("fits in range")
}
}
----------------------------------
fits in range
range 를 벗어난 숫자를 확인한다면
fun main() {
val list = listOf("a", "b", "c")
if (-1 !in 0..list.lastIndex) {
println("-1 is out of range")
}
if (list.size !in list.indices) {
println("list size is out of valid list indices range, too")
}
}
---------------------------------------------------------------------
-1 is out of range
list size is out of valid list indices range, too
range 에 속한 숫자 순차적으로 접근합니다.
fun main() {
for (x in 1..5) {
print(x)
}
}
-----------------------
12345
또는 진행식
fun main() {
for (x in 1..10 step 2) {
print(x)
}
println()
for (x in 9 downTo 0 step 3) {
print(x)
}
}
--------------------------------------
13579
9630
Collections
collection 반복 시키기:
fun main() {
val items = listOf("apple", "banana", "kiwifruit")
for (item in items) {
println(item)
}
}
------------------------------------------------------
apple
banana
kiwifruit
`in` 연산자를 사용해서 collection 에 포함된 객체 확인하는 법:
fun main() {
val items = setOf("apple", "banana", "kiwifruit")
when {
"orange" in items -> println("juicy")
"apple" in items -> println("apple is fine too")
}
}
------------------------------------------------------------
apple is fine too
lambda 표현식으로 collection 을 filter 하고 map 하기
fun main() {
val fruits = listOf("banana", "avocado", "apple", "kiwifruit")
fruits
.filter { it.startsWith("a") }
.sortedBy { it }
.map { it.uppercase() }
.forEach { println(it) }
}
--------------------------------------------------------------------
APPLE
AVOCADO
Nullable 값과 null 확인하기
`null` 값이 허용 될 때 참조할 때 반드시 명시적으로 nullable 이라고 표시해야합니다. Nullable 형식의 이름은 끝에 `?` 가 붙습니다.
만일 `str` 변수가 정수를 소유하고 있지 않다면 `null` 을 응답 합니다:
fun parseInt(str: String): Int? {
// ...
}
함수가 nullable 값을 반환하도록 해봅시다
fun parseInt(str: String): Int? {
return str.toIntOrNull()
}
fun printProduct(arg1: String, arg2: String) {
val x = parseInt(arg1)
val y = parseInt(arg2)
// Using `x * y` yields error because they may hold nulls.
if (x != null && y != null) {
// x and y are automatically cast to non-nullable after null check
println(x * y)
}
else {
println("'$arg1' or '$arg2' is not a number")
}
}
fun main() {
printProduct("6", "7")
printProduct("a", "7")
printProduct("a", "b")
}
--------------------------------------------------------------------------------
42
'a' or '7' is not a number
'a' or 'b' is not a number
또는
fun parseInt(str: String): Int? {
return str.toIntOrNull()
}
fun printProduct(arg1: String, arg2: String) {
val x = parseInt(arg1)
val y = parseInt(arg2)
// ...
if (x == null) {
println("Wrong number format in arg1: '$arg1'")
return
}
if (y == null) {
println("Wrong number format in arg2: '$arg2'")
return
}
// x and y are automatically cast to non-nullable after null check
println(x * y)
}
fun main() {
printProduct("6", "7")
printProduct("a", "7")
printProduct("99", "b")
}
------------------------------------------------------------------------
42
Wrong number format in arg1: 'a'
Wrong number format in arg2: 'b'
자료형 확인과 자동 형변환
`is` 는 자료형의 인스턴스인지 확인합니다. 만일 불변의 지역 변수 또는 속성일 경우 특정 자료형인지 확인 할 수 있으며, 명시적으로 형변환을 할 필요가 없습니다.
fun getStringLength(obj: Any): Int? {
if (obj is String) {
// `obj` 는 이 분기내에서 자동으로 `String` 으로 변환됩니다.
return obj.length
}
// `obj` 는 자료형 확인 분기에서 벗어났으므로 여전히 `Any` 형입니다.
return null
}
fun main() {
fun printLength(obj: Any) {
println("Getting the length of '$obj'. Result: ${getStringLength(obj) ?: "Error: The object is not a string"} ")
}
printLength("Incomprehensibilities")
printLength(1000)
printLength(listOf(Any()))
}
-----------------------------------------------------------------------------------
Getting the length of 'Incomprehensibilities'. Result: 21
Getting the length of '1000'. Result: Error: The object is not a string
Getting the length of '[java.lang.Object@7e6cbb7a]'. Result: Error: The object is not a string
또는:
fun getStringLength(obj: Any): Int? {
if (obj !is String) return null
// 이 분기에서는 `obj` 가 자동으로 `String` 으로 형변환 됩니다.
return obj.length
}
fun main() {
fun printLength(obj: Any) {
println("Getting the length of '$obj'. Result: ${getStringLength(obj) ?: "Error: The object is not a string"} ")
}
printLength("Incomprehensibilities")
printLength(1000)
printLength(listOf(Any()))
}
------------------------------------------------------------------
Getting the length of 'Incomprehensibilities'. Result: 21
Getting the length of '1000'. Result: Error: The object is not a string
Getting the length of '[java.lang.Object@7e6cbb7a]'. Result: Error: The object is not a string
또는:
fun getStringLength(obj: Any): Int? {
// `obj` 는 `&&` 의 우측에서 자동으로 `String` 으로 변환됩니다.
if (obj is String && obj.length > 0) {
return obj.length
}
return null
}
fun main() {
fun printLength(obj: Any) {
println("Getting the length of '$obj'. Result: ${getStringLength(obj) ?: "Error: The object is not a string"} ")
}
printLength("Incomprehensibilities")
printLength("")
printLength(1000)
}
'프로그래밍언어 > Kotlin' 카테고리의 다른 글
[kotlin] 자주 사용되는 구문 (2) | 2025.02.09 |
---|