함수를 정의할 때 fun 키워드를 사용합니다. val은 읽기 전용 변수, var은 변경 가능한 변수입니다.
fun main(args: Array<String>) {
println("Hello, World!")
}
if
, for
, while
문은 조건을 확인하는 것이지 값을 바꾸진 않습니다.fun max(a: Int, b: Int): Int {
return if ( a > b ) a else b
}
블록이 본문인 함수
라고 부릅니다.if는 코틀린에서 식이며, 값을 만들어 냅니다.
fun max(a: Int, b: Int): Int = if (a>b) a else b
식이 본문인 함수
라고 합니다.fun max(a: Int, b: Int) = if (a>b) a else b
컴파일러가 타입을 분석해 정해주는 기능을 타입 추론
이라고 부릅니다. // 초기화 식
val question = "삶, 우주, 그리고 모든 것에 대한 궁극적인 질문" // String
val answer = 42 // Int
val yearsToCompute = 7.5e6 // Double
// 초기화 식 X
val answer: Int
answer = 42
val languages = arrayListOf("Java") // 불변 참조
languages.add("Kotlin") // 참조가 가리키는 객체 내부를 변경
객체의 내부 값은 변경
할 수 있습니다.타입은 고정
돼야합니다. Int로 선언된 변수에 String값을 대입할 수 없습니다.문자열 템플릿을 사용하면, 문자열을 연결하지 않아도 되므로 코드가 간결해집니다. 변수 이름 앞에 $를 붙이거나, 식을 ${식}처럼 ${}로 둘러싸면 변수나 식의 값을 문자열 안에 넣을 수 있습니다.
fun main(args: Array<String>) {
val name = if (Args.size > 0) args[0] else "Kotlin"
println("Hello, ${name}!") // Hello, Bob!
}
코틀린에서는 값 객체 클래스를 아주 간결하게 표현할 수 있습니다.
public class Person {
private String name;
private Boolean isMarried;
public Person(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
...
}
Person person = new Person("Bob", true);
person.getName(); // Bob
person.isMarried(); // true
1 class Person(
2 val name: String,
3 var isMarried: Boolean
4 )
5 val person = Person("Bob", true)
6 person.name // Bob
7 person.isMarried // true
8 person.isMarried = false
9 person.isMarried // false
2 : val
읽기 전용 프로퍼티입니다. private field + public getter를 제공합니다.
3 : var
private field + public getter/setter를 제공합니다.
5 : new 키워드없이 생성자를 호출합니다.
6 : 프로퍼티 이름을 직접 사용해도 코틀린이 자동으로 getter를 호출해줍니다.
8 : setter도 마찬가지로 프로퍼티 이름을 직접 사용해도 자동으로 setter를 호출해줍니다.
class Rectangle(val height: Int, val width: Int) {
val isSquare: Boolean
get() {
return height == width
}
// get() = height == width // 위의 get과 동일
}
val rectangle = Rectangle(41, 43)
rectangle.isSquare // false
package
import
when은 자바의 switch와 비슷하지만, 더 강력합니다.
eunm class Color (
val r: Int, val g: Int, val b: Int
) {
RED(255, 0, 0),
ORAGNE(255, 165, 0);
fun rgs() = (r*256 + g) * 256 + b
}
fun getMnemonic(color: Color) =
when (color) {
Color.RED -> "Richard"
Color.ORAGNE -> "Of"
Color.YELLOW -> "York"
Color.GREEN -> "Gave"
Color.BLUE -> "Battle"
Color.INDIGO -> "In"
Color.VIOLET -> "Vain"
}
when도 값을 만들어내는 식
입니다.fun getWarmth(color: Color) = when(color) {
Color.RED, Color.ORANGE -> "warm"
Color.GREEN -> "neutral"
}
fun mix(c1: Color, c2: Color) =
when (setOf(c1, c2)) {
setOf(RED, YELLOW) -> ORANGE
setOf(YELLOW, BLUE) -> GREEN
else -> throw Exception("Dirty Color")
}
fun mixOptimized(c1: Color, c2: Color) =
when {
(c1 == RED && c2 == YELLOW) ||
(c1 == YELLOW && c2 == RED) -> ORANGE
(c1 == YELLOW && c2 == BLUE) ||
(c1 == BLUE && c2 == YELLOW) -> GREEN
else -> throw Exception("Dirty Color")
어떤 변수의 타입을 검사하고 나면 그 변수를 캐스팅하지 않아도 검사한 타입의 변수처럼 사용할 수 있습니다.
그런 경우 컴파일러가 스마트 캐스트를 활용해 자동으로 타입을 바꿔줍니다.
interface Expr
class Num(val value: Int) : Expr
class Sum(val left: Expr, val right: Expr) : Expr
fun eval(e: Expr): Int {
if(e is Num) {
val n = e as Num
return n.value
}
if(e is Sum) {
return eval(e.right) + eval(e.left)
}
throw IllegalArgumentException("Unknown expression")
}
is로 검사하고 나면 컴파일러가 캐스팅을 수행
해줍니다. 이를 스마트 캐스트
라고 부릅니다.fun eval(e: Expr): Int =
when (e) {
is Num -> e.value
is Sum -> eval(e.right) + eval(e.left)
else -> throw IllegalArgumentException("Unknown expression")
}
for, while, do-while 루프는 자바가 제공하는 같은 키워드의 기능과 비슷합니다.
하지만 코틀린의 for는 자바의 for보다 더 편리합니다. 특히 맵을 이터레이션하거나 이터레이션하면서 컬렉션의 원소와 인덱스를 함께 사용해야 하는 경우 코틀린의 for가 더 편리합니다.
fun fizzBuzz(i: Int) = when {
i % 15 == 0 -> "FizzBuzz "
i % 3 == 0 -> "Fizz "
i % 5 == 0 -> "Buzz "
}
// 1부터 100까지 1씩 증가
for ( i in 1..100 ) {
fizzBuzz(i)
}
// 100부터 1까지 2씩 감소
for ( i in 100 downTo 1 step 2 ) {
fizzBuzz(i)
val binaryReps = TreeMap<Cahr, String> ()
for (c in 'A'..'F') {
val binary = Integer.toBinaryString(c.toInt())
binaryReps[c] = binary
}
for ((letter, binary) in binaryReps) {
println("${letter} = ${binary}")
}
val list = arrayListOf("10,", "11", "1001")
for ((index, elements) in list.wintIndex()) {
println("${index}: ${element}")
코틀린 예외 처리는 자바와 비슷합니다. 다만 코틀린에서 함수가 던질 수 있는 예외를 선언하지 않아도 됩니다.
if (percentage !in 0..100) {
throw IllegalArgumentException("A percentage ...")
}
fun readNumber(reader: BufferedReader) {
val number = try {
Integer.parseInt(reader.readLine())
} catch (e: NumberFormatException) {
return
}
}