2 코틀린 기초.md

  • 함수, 변수, 클래스, enum, 프로퍼티를 선언하는 방법

  • 제어 구조

  • 스마트 캐스트

  • 예외 던지기와 예외 잡기

  • 변수, 함수, 클래스, 프로퍼티, 제어 구조, 스마트 캐스트 (타입 검사와 타입 캐스트, 타입 강제 변환을 하나로 엮은 기능), 예외처리

2.1 기본 요소: 함수와 변수

2.1.1 Hello, World!

fun main(args: Array<String>) {
  println("Hello, world!")
}
  • 함수 선언할 때 fun 키워드 사용

  • 파라미터 이름 뒤에 타입을 쓴다.

  • 함수를 최상위 수준에 정의할 수 있다. 클래스 안에 함수를 넣을 필요 없음.

  • 배열도 일반적인 클래스처럼. 배열 처리를 위한 문법이 따로 존재하지 않음

  • System.out.prinln 대신 println. 코틀린은 표준 자바 라이브러리 함수를 간결하게 사용할 수 있게 감싼 래퍼들을 제공함.

  • 세미콜론 붙이지 않음

2.1.2 함수

REPL 에서 실습

  • 문(statement)과 식(expression)의 구분

    • 코틀린에서 if 는 식이지 문이 아니다.

    • 식은 값을 만들어 내며 다른 식의 하위 요소로 계산에 참여할 수 있음

    • 문은 자신을 둘러싸고 있는 가장 안쪽 블록의 최상위 요소로 존재하며 아무런 값을 만들어내지 않는다

    • 반면 대입문은 자바에서는 식이었으나 코틀린에서는 문

식이 본문인 함수

  • 본문이 중괄호로 둘러싸인 함수를 블록이 본문인 함수라 부름

  • 등호와 식으로 이뤄진 함수를 식이 본문인 함수라 부름

  • 인텔리J 아이디어 팁. 이 두 방식의 함수를 서로 변환하는 메뉴가 있음.

  • 반환 타입을 생략

  • 타입 추론을 해 주기 때문.

    • type inference: 컴파일러가 타입을 분석해 프로그래머 대신 프로그램 구성 요소의 타입을 정해주는 기능

  • 식이 본문인 함수의 반호나 타입만 생략 가능하다는 점에 유의

  • 블록이 본문인 함수가 값을 반환한다면 반드시 반환 타입을 지정하고 return 문을 사용해 반환 값을 명시해야 함.

2.1.3 변수

  • 자바는 타입이 맨 앞에 온다. (타입을 생략할 경우 식과 변수 선언을 구별할 수 없다.)

  • 코틀린에서는 타입 지정을 생략하는 경우가 흔함. 키워드로 변수 선인 시작. 변수 이름 뒤에 타입을 명시하거나 생략하게 허용.

원한다면 타입을 명시해도 됨

부동소수점 상수를 사용하면 변수 타입은 Double 이 됨

초기화 식을 사용하지 않고 변수 선언하려면 변수 타입 반드시 명시

초기화 식이 없다면 컴파일러가 타입을 추론할 수 없기 때문에 반드시 지정

변경 가능한 변수와 변경 불가능한 변수

  • val(value) - 변경 불가능한(immutable) 참조를 저장하는 변수. 자바의 final 변수

  • var(variable) - 변경 가능한(mutable) 참조. 자바의 일반 변수

variable이 형용사로 쓰이면 '변할 수 있는'이라는 뜻. 변수 말 자체가 이미 변화라는 개념이 내재돼 있음. 함수형 프로그래머 중에는 변경 불가능한 변수를 표현하기 위해 변수라는 단어 대신 '값'이나 '이름'이라는 단얼르 사용하기도 함. 문맥에 따라 '값'과 '이름'을 혼용하기도 함.

  • val 을 기본으로 하고 필요할 때에만 var 로 변경

  • val 변수는 한번만 초기화돼야 함

  • val 참조 자체는 불변일지라도 그 참조가 가리키는 객체의 내부 값은 변경될 수 있다

  • var 키워드 사용하면 변수의 값을 변경할 수 있지만 변수의 타입은 고정돼 바뀌지 않음.

  • 아래는 컴파일 오류. Error: type mismatch

  • 어떤 타입의 변수에 다른 타입의 값을 저장하고 싶다면 변환 함수를 써서 값을 변수의 타입으로 변환하거나, 값을 변수에 대입할 수 있는 타입으로 강제 형 변환(coerce)해야 한다. 원시 타입의 변환에 대해서는 6.2.3절에서 다룸

2.1.4 더 쉽게 문자열 형식 지정: 문자열 템플릿

  • name 이라는 변수를 선언하고 문자열 리터럴 안에서 그 변수를 사용. 변수 앞에 $ 를 추가

  • 자바의 문자열 접합 연산 ("Hello, " + name + "!")과 동일한 기능을 하지만 좀 더 간결

  • $ escape 하려면 $ 하면 됨

  • 복잡한 식도 중괄호({})로 둘러싸서 문자열 템플릿 안에 넣을 수 있음.

  • 한글을 문자열 템플릿에서 사용할 경우 주의할 점

    • 변수 이름에 한글이 들어갈 수 있음.

    • '$name님' unresolved reference 오류. ${name} 처럼 중괄호로 감싸는게 좋음

  • 중괄호 식 안에서 큰 따옴표 사용 가능

  • 3.5절에서 더 많이.

2.2 클래스와 프로퍼티

  • 리스트 2.3 간단한 자바 클래스 Person

  • 필드가 들어나면 생성자의 파라미터가 늘어나고 대입문의 수도 늘어남.

  • 코틀린에서는 훨씬 더 적은 코드로 작성할 수 있음.

  • 코틀린으로 변환

2.2.1 프로퍼티

  • 클래스라는 개념의 목적은 데이터를 캡슐화(encapsulate)라고 캡슐화한 데이털르 다루는 코드를 한 주체 아래 가두는 것

  • 자바에서는 데이터를 필드(field)에 저장하며, 멤버 필드의 가시성은 보통 비공개(private)

  • 클래스는 자신을 사용하는 클라이언트가 그 데이터에 접근한느 통로로 쓸 수 있는 접근자 메소드(accessor method)를 제공함.

  • 읽기 위한 게터(getter), 변경할 경우 세터(setter)를 추가 제공

  • 자바에서는 필드와 접근자를 한데 묶어 프로퍼티(property)라고 부름. 프로퍼티라는 개념을 활용하는 프레임워크가 많음. (Lombok 등)

  • 코틀린은 프로퍼티를 언어 기본 기능으로 제공. 코틀린 프로퍼티는 자바의 필드와 접근자 메소드를 완전히 대신함.

  • 리스트 2.6 자바에서 Person 클래스를 사용하는 방법

  • 리스트 2.7 코틀린에서 Person 클래스 사용하기

2.2.2 커스텀 접근자

  • get() = height == width 라고 해도 됨.

  • 파라미터가 없는 함수를 정의하는 방식과 커스텀 게터를 정의하는 방식. 두 방식 모두 비슷. 구현이나 성능상 차이는 없음. 차이는 가독성. 클래스의 특성을 정의하고 싶다면 프로퍼티로 그 특성을 정의해야 함.

2.2.3 코틀린 소스코드 구조: 디렉터리와 패키지

  • 리스트 2.8 클래스와 함수 선언을 패키지에 넣기

  • 리스트 2.9 다른 패키지에 있는 함수 임포트하기

2.3 선택 표현과 처리: enum과 when

2.3.1 enum 클래스 정의

  • 리스트 2.10 간단한 enum 클래스 정의하기

리스트 2.11 프로퍼티와 메소드가 있는 enum 클래스 선언하기

2.32 when으로 enum 클래스 다루기

리스트 2.12 when을 사용해 올바른 enum 값 찾기

리스트 2.13 한 when 분기 안에 여러 값 사용하기

리스트 2.14 enum 상수 값을 임포트해서 enum 클래스 수식자 없이 enum 사용하기

2.3.3 when과 임의의 객체를 함꼐 사용

  • 리스트 2.15 when의 분기 조건에 여러 다른 객체 사용하기

2.3.4 인자 없는 when 사용

  • 리스트 16 인자가 없는 when

  • when 에 아무 인자도 없으려면 각 분기의 조건이 불리언 결과를 계산한느 식이어야 함.

  • mixOptimized 함수는 앞에서 살펴본 mix 함수와 같은 일을 함.

  • mixOptimized는 추가 객체를 만들지 않는다는 장점이 있지만 가독성은 더 떨어짐

  • 이제 when을 사용하는 과정에서 스마트 캐스트가 쓰이는 예를 살펴보자

2.3.5 스마트 캐스트: 타입 검사와 타입 캐스트를 조합

  • 리스트 2.17 식을 표현하는 클래스 계층

  • 리스트 2.18 if 연쇄를 사용해 식을 계산하기

그림 2.5 IDE는 배경색으로 스마트 캐스트를 표시해준다. (e.right, e.left 의 e 가 강조 표시)

2.3.6 리팩토링: if를 when으로 변경

  • 리스트 2.19 값을 만들어내는 if 식

  • if의 분기에 식이 하나밖에 없다면 중괄호를 생략해도 됨. if 분기에 블록을 사용하는 경우 그 블록의 마지막 식이 그 분기의 결과 값임.

  • 리스트 2.20 if 중첩 대신 when 사용하기

2.3.7 if와 when의 분기에서 블록 사용

  • 리스트 2.21 분기에 복잡한 동작이 들어가 있는 when 사용하기

2.4 대상을 이터레이션: while과 for 루프

2.4.1 while 루프

2.4.2 수에 대한 이터레이션: 범위와 수열

  • 리스트 2.22 when을 사용해 피즈버즈 게임 구현하기

    ```kotlin

    fun fizzBuzz(i: Int) = when {

    i % 15 == 0 -> "FizzBuzz "

    i % 3 == 0 -> "Fizz "

    i % 5 == 0 -> "Buzz "

    else -> "$i "

    }

    for (i in 1..100) { ... print(fizzBuzz(i)) ... }

라는 코드는

라는 자바 코드와 같다.

출력

  • withIndex의 정체에 대해서는 3장에서 살펴본다.

2.4.4 in으로 컬렉션이나 범위의 원소 검사

  • 리스트 2.25

  • 리스트 2.26

2.5 코틀린의 예외 처리

  • 예외를 던지는 방법

  • 자바와 달리 코틀린의 throw는 식이므로 다른 식에 포함될 수 있다.

  • p282 활용사례

    ```

    fun fail(message: String): Nothing {

    throw IllegalStateException(message)

    }

var address = company.address ?: fail("No_address") println(address.city)

2.5.2 try를 식으로 사용

  • 리스트 2.28 try를 식으로 사용하기

아무것도 출력되지 않는다.

  • 리스트 2.29 catch에서 값 반환하기

예외가 발생했으므로 함수가 "null"을 출력한다.

2.6 요약

  • 함수를 정의할 때 fun 키워드 사용. val과 var는 각각 읽기 전용 변수와 변경 가능한 변수 선언할 때 쓰임

  • 문자열 템플릿을 사용하면 문자열을 연결하지 않아도 되므로 코드가 간결해진다. 변수 이름 앞에 $를 붙이거나, 식을 ${식}처럼 ${}로 둘러싸면 변수나 식의 값을 문자열 안에 넣을 수 있다.

  • 코틀린에서는 값 객체 클래스를 아주 간결하게 표현할 수 있다.

  • 다른 언어에도 있는 if는 코틀린에서 식이며, 값을 만들어낸다.

  • 코틀린 when은 자바의 switch와 비슷하지만 더 강력하다.

  • 어떤 변수의 타입을 검사하고 나면 굳이 그 변수를 캐스팅하지 않아도 검사한 타입의 변수처럼 사용할 수 있다. 그런 경우 컴파일러가 스마트 캐스트를 활용해 자동으로 타입을 바꿔준다.

  • for, while, do-while 루프는 자바가 제공하는 같은 키워드의 기능과 비슷하다. 하지만 코틀린의 for는 자바의 for보다 더 편리. 특히 맵을 이터레이션하거나 이터레이션하면서 컬렉션의 원소와 인덱스를 함께 사용해야 하는 경우 코틀린의 for가 더 편리

  • 1..5와 같은 식은 범위를 만들어낸다. 범위와 수열은 코틀린에서 같은 문법을 사용하며, for 루프에 대해 같은 추상화를 제공. 어떤 값이 범위 안에 들어 있거나 들어있지 않은지 검사하기 위해 in이나 !in을 사용

  • 코틀린 예외 처리는 자바와 비슷. 다만 코틀린에서는 함수가 던질 수 있는 예외를 선언하지 않아도 됨.

Last updated

Was this helpful?