본문 바로가기

Dev Book/Kotlin IN ACTION

CH2(2.1~2.3). 코틀린 기초

2.1 함수와 변수

- 코틀린 함수의 기본 정의

fun max(a: Int, b: Int): Int{
	return if (a>b) a else b
}

- 식이 본문인 함수: 본문이 중괄호로 둘러싸인 함수를 블록이 본문인 함수라 부르고, 등호와 식으로 이뤄진 함수를 식이 본문이 함수라고 부른다. 코틀린에서는 식이 본문인 함수가 자주 쓰인다. 코틀린에서는 if, when, try 등이 결과를 만드는 식으로서 함수 본문 식에 자주 사용된다. 이 경우 굳이 사용자가 반환타입을 적지 않아도 컴파일러가 함수 본문 식을 분석해서 식의 결과 타입을 함수 반환 타입으로 정해준다.(타입 추론. 식이 본문인 함수의 반환 타입만 생략 가능하다!)

 

- 변수: 코틀린에서는 키워드로 변수 선언을 시작하는 대신 변수 이름 뒤에 타입을 명시하거나 생략하게 허용한다. 초기화 식을 사용하면 컴파일러가 알아서 변수 타입을 지정해주지만, 초기화 식을 사용하지 않고 변수를 선언하려면 변수 타입을 반드시 명시해야 한다.

  • val. 변경 불가능한 참조를 저장하는 변수. 초기화하고 나면 재대입이 불가능하다. 참조 자체는 불변일지라도 그 참조가 가리키는 객체의 내부 값은 변경될 수 있다.
  • var: 변경 가능한 참조. 
  • 기본적으로는 모든 변수를 val 키워드를 사용해 선언하고 나중에 꼭 필요한 경우에만 var로 변경해 사용하는 것을 권장한다.  -> 함수형 코드에 가까워짐.

- 문자열 템플릿. 문자열 리터럴의 필요한 곳에 변수를 넣되 변수 앞에 $를 추가해 사용한다. 복잡한 식도 {}로 둘러싸서 문자열 템플릿 안에 넣을 수 있다.

2.2 클래스와 프로퍼티

- 코틀린의 기본 가시성은 public이므로 이런 경우 변경자를 생략해도 된다.

- 자바에서는 필드와 접근자를 한데 묶어 프로퍼티라고 부르며, 코틀린은 프로퍼티를 언어 기본 기능으로 제공한다. val로 선언한 프로퍼티는 읽기 전용이며, var로 선언한 프로퍼티는 변경 가능하다.

 

class Person{
	val name: String,
    var isMarried: Boolean
}

 

- 코틀린에서는 new 키워드를 사용하지 않고 생성자를 호출하고, 게터를 호출하는 대신 프로퍼티 이름을 직접 사용해도 된다. 세터 역시 자바에서는 person.setMarried(false)를 코틀린에서는 person.isMarried=false로 쓴다.

 

- 커스텀 접근자: 프로퍼티의 접근자를 직접 작성할 수 있다.

 

class Rectangle(val height: Int, val width: Int){
	val isSquare: Boolean
    	get(){
        	return height == width
        }
}

 

- 이 경우 get() = height == width 로 써도 된다.

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

- enum 클래스 정의: 코틀린에서 enum은 소프트 키워드라 부른다. enum은 class 앞에 있을 때 특별한 의미를 지니고, 다른 곳에서 이름에 사용할 수 있다. 그러나 키워드인 class는 class라는 이름을 사용할 수 없다. 자바와 마찬가지로 enum은 단순히 값을 열거할 뿐 아닌 enum class 안에 프로퍼티나 메소드를 정의할 수 있다.

 

enum class Color(
	val r:Int, val g:Int, val b:Int
) {
	RED(255,0,0), ORANGE(255,165,0), 
    YELLOW(255,255,0), GREEN(0,255,0), BLUE(0,0,255),
    INDIGO(75,0,130), VIOLET(238,130,238);
    
    fun rgb() = (r*256 + g) * 256 + b
}

 

- when 사용하기: when은 자바의 switch를 대체한다. if와 마찬가지로 값을 만들어내는 식이므로 식이 본문인 함수에 when을 바로 사용할 수 있다.

 

fun getWarmth(color: Color) = when(color){
	Color.RED, Color.ORANGE, Color.YELLOW -> "warm"
    Color.GREEN -> "neutral"
    Color.BLUE, Color.INDIGO, Color.VIOLET -> "cold"
}

 

- enum 상수 값을 임포트 해서 enum 클래스 수식자 없이 사용 가능하다.

- switch와 달리 코틀린 when의 분기 조건은 임의의 객체를 허용한다. 

 

fun mix(c1:Color, c2:Color) = 
	when(setOf(c1, c2)) {
	setOf(RED, YELLOW) -> ORANGE
    	setOf(YELLOW, BLUE) -> GREEN
    	setOf(BLUE, VIOLET) -> INDIGO
    	else -> throw Exception("Dirty color")
	}

 

- 인자가 없는 when 식을 사용하면 불필요한 객체 생성을 막을 수 있다. 추가 객체를 만들지는 않지만, 가독성은 떨어진다.

 

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")
    }

 

- 스마트 캐스트: 코틀린에서는 is를 사용해 변수 타입을 검사한다. 어떤 변수가 원하는 타입인지 일단 is로 검사하고 나면 굳이 변수를 원하는 타입으로 캐스팅하지 않아도 마치 처음부터 그 변수가 원하는 타입으로 선언된 것처럼 사용할 수 있다. (실제로는 컴파일러가 캐스팅을 수행해준다.) 이를 스마트 캐스트라고 부른다. 스마트 캐스트는 is로 변수에 든 값의 타입을 검사한 다음에 그 값이 바뀔 수 없는 경우에만 작동하므로, 프로퍼티에 대해 사용한다면 그 프로퍼티는 반드시 val이어야 하며, 커스텀 접근자를 사용한 것이면 안된다.

- 원하는 타입으로 명시적으로 타입 캐스팅하려면 as 키워드를 사용한다.