아토믹 코틀린 1부 프로그래밍 기초

smpl published on
5 min, 845 words

Tags: kotlin

아토믹 코틀린 책의 1부 프로그래밍 기초 챕터를 읽고, 읽은 내용을 정리해봅니다. 공부하면서 개인적으로 다른 언어와 달랐던 점, 인상깊었던 점 혹은 기억해야할 점들만 적었습니다.

코틀린에 영향을 끼친 언어들

  • FORTRAN
  • LISP
  • ALGOL
  • COBOL
  • BASIC
  • Simula
  • PASCAL
  • C
  • Smalltalk
  • C++
  • Python
  • Haskell
  • Java
  • Javascript
  • C#
  • Scala
  • Groovy

코틀린의 장점

  • 왜 코틀린인가?
    • 가독성
    • 도구(JetBrains)
    • 다중 패러다임(명령형, 함수형, 객체지향 프로그래밍)
    • 다중 플랫폼(JVM, 안드로이드 ART, 자바스크립트, 네이티브)
  • 특징
    • 노력이 필요없는 자바 상호운용성
    • 빈값 표현 방식

Hello, World!

entry point

fun main() {}

주석

// one line comment
/* multi line
    comment */

;로 문장을 끝낼 필요가 없다.

var와 val

  • var : 식별자가 담고 있는 값이 변할 수 있다.(mutable) 내용을 '재대입'할 수 있다.
var 식별자 = 1 // 초기화
식별자 = 식별자 + 1
식별자 += 1
  • val : 식별자의 값을 단 한번만 초기화할 수 있고 값을 재대입할 수 없다.(immutable)
val 식별자 = 1 // 초기화
식별자 = 식별자 + 1 // 오류

데이터 타입

  • 코틀린은 타입추론을 지원한다. 변수를 만들 때 타입을 명시하는 문법은 다음과 같다.
// var 식별자: 타입 = 초기화
var n: Int = 1
var d: Double = 1.2
var b: Boolean = true
var s: String = "hello"
var c: Char = 'z'
var lines: String = """큰 따옴포 세개로
여러 줄 문자열 리터럴을 편하게
사용할 수 있다.
삼중 따옴표 String 혹은 Raw String 이라고 부른다.
  • 타입들
    • Byte, Short, Int, Long
    • Float, Double
    • UByte, UShort, UInt, ULong
    • Boolean
    • Char (16비트 유니코드 문자, 16비트 이하만 저장 가능, 2바이트를 넘을 수 없기 때문에, 차라리 UCS-2라고 간주 가능할 것 같다.)
    • String (approximately 2bytes per character, 유니코드를 온전하게 담을 수 있다.)
    • UByteArray, UShortArray, UIntArray, ULongArray
    • UIntRange
    • UIntProgression
    • Array

함수

기본적인 형태

fun 함수이름(p: 타입, p2: 타입, ...): 반환타입 {
    코드
    return 결과
} 

의미있는 반환결과를 제공하지 않는 함수의 반환 타입은 Unit이다. 반환 타입의 Unit은 생략할 수 있다.

fun sayHello() {
  println("Hello!")
}

fun sayGoodbye() : Unit {
  println("Goodbye!")
}

함수 본문이 하나의 식으로만 이루어진 경우

//fun 함수이름(p1: 타입, p2: 타입, ...): 반환타입 = 식
fun multiply(x: Int): Int = x * 2

if 식

if 괄호 안에 있는 식은 반드시 true나 false로 평가되어야 한다.

val num = 10
if (num > 100) {
  println("bigger than 100")
} else {
  println("lesser than or same as 100")
}

val result = if (num > 100) 4 else 42

문자열 템플릿

문자열 리터럴 안에서 $ 문자로 식을 평가할 수 있다. raw string에서도 $식별자나 ${식}을 쓸 수 있다.

println("answer is $answer")
println("${if (condition) 'a' else 'b'}")

따옴표"가 들어가야 할 경우 """로 감싸거나, \"와 같이 표현한다.

수 타입

숫자 사이에 가독성을 위해 _ 밑줄을 넣을 수 있다.

val two_millions = 2_000_000
println(two_millions)

정수 나눗셈의 결과는 정수로, 나머지는 버림한다.

각 타입의 최대 값은 MAX_VALUE로 구할 수 있다.

val i: Int = Int.MAX_VALUE

코틀린은 넘침 가능성을 컴파일 시점에 경고를 해줄 수 있지만, 항상 체크해주지는 못 하며, 실행 중에 넘침 여부를 검사하면 성능상 영향이 있기 때문에 넘침을 방지해주지 않는다.

불리언

(새로운 내용 없음)

while로 반복하기

while (불리언 식) {
  // 반복 코드
}

do {
  // 반복 코드
} while (불리언 식)

루프와 범위

//for (v in 값들) {
//   v를 이용한 반복 코드
//}

// 양 끝을 포함. 1부터 3까지 3번 반복. 
// 1..3 을 이터레이션이라고 부른다. 이터레이션은 정수, 문자처럼 연속적이지 않은 경우만 가능하며 실수는 사용 불가하다.
for (i in 1..3) {
  println("Hey $i")
}

// a부터 z까지 반복
for (i in 'a'..'z') {
  println("$i")
}

// until 다음의 값 미포함. 1부터 2까지 2번 반복.
for (i in 1 unil 3) {
  println("Hey $i")
}

// 범위 타입
val range1 = 1..10
val range2 = 0 until 10

for (i in range1) {
  println("hello $i")
}

for (i in range2) {
  println("hello $i")
}

val range3 = 5 downTo 1         // 5, 4, 3, 2, 1
val range4 = 0..9 step 2        // 0 2 4 6 8
val range5 = 0 until 10 step 3  // 0 3 6 9
val range6 = 9 downto 2 step 3  // 9 6 3

// 문자열도 이터레이션 가능
for (c in "Quantumized") {
  println(ch + 1)
}

조건이 필요하지 않고 단순히 일정 횟수만큼 반복만 하고 싶다면 표준 라이브러리 함수 repeat을 사용할 수 있다.

repeat(2) {
  println("hello!")
}

in 키워드

in 키워드는 for의 이터레이션과 조건 검사 모두로 쓰인다. for 밖의 in 키워드는 어떤 값이 주어진 범위 안에 들어 있는지 검사한다.

val a = 10
println(a in 1..100)        // true
println('k' in "kotlin")    // true
println('c' in "kotlin")    // false
println("ab" in "aa".."az") // true
println("ba" in "aa".."az") // false

Double도 사실은 범위를 만들 순 있지만, 구간 내에 포함되는지 여부를 검사할 때만 Double의 범위를 쓸 수 있다.

val r = 1.0..10.0
val chk1 = 0.999999 in r    // false
val chk2 = 5.0 in r         // true
val chk3 = 10.0 in r        // true
val chk4 = 10.00000001 in r // false

kotlin 1.8부터는 반 열린 범위(semi-open range)를 쓸 수 있다.

println(0..<10) // 0 1 2 3 ... 9

식과 문

문(statement)은 부수효과를 일으키지만 결과를 내놓지 않는다. 식(expression)은 항상 결과를 만들어 낸다.

for는 statement이고 부수효과를 만들어내기위해 사용한다.

모든 함수는 expression이다. 함수가 Unit을 반환하고, 부수효과를 갖고 있더라도 여전히 함수 호출 결과를 변수에 대입할 수 있다.

Unit 타입에는 오직 Unit이라는 값만 대입 가능하다.

fun unitFn() = Unit

val u1 = unitFn() // Unit
val u2 = println(42) // Unit

if는 식을 만들 수 있다.

증가 및 감소 연산자 ++--는 식이다.

증가 및 감소 연산자는 전위 혹은 후위로 쓸 수 있지만, 되도록 다른 식 안에 섞어 쓰지 않는 것이 좋다.