가변 인수

가변 인수를 받을 때는 앞에 ``kt vararg`` 키워드를 붙인다.
```kt
fun listOf<T>(vararg values: T): List<T> { ... }
```

이미 배열에 들어있는 원소를 가변 길이 인자로 넘길 때는 spread 연산자 ``kt *``를 붙인다.
```kt
val list = listOf("args: ", *args)
```
자바 코드로 변환해보면 호출하는 측에서 `` SpreadBuilder``라는 객체에 ``kt *``로 지정된 인자를 모두 풀어서 추가하고, 이를 배열로 만들어 넘기게 된다.

infix(중위) 함수 호출 구문과 딕셔너리( 맵 )

함수 선언 시에 ``kt infix``를 붙이면 ``kt 3.mul(10)``을 ``kt 3 mul 10``으로 쓸 수 있도록 하는 건데, 가독성에 이점이 있는 듯.

맵 만들 때 쓰면 편하다. * 파이썬의 딕셔너리가 자바에서는 맵이다.

```kt

>>> val numbers = mapOf("zero" to 0, "one" to 1)

>>> println(numbers)

```


삼항 연산자가 없는 대신 if로 처리할 수 있다.

코틀린에서 ``kt if``는 단순한 문장(statement)이 아니라 결과를 반환하는 식(expression)이다.
Note ) ``kt if  when  try`` 모두 식(expression)이다.
```kt
var k = if (a > b) a else b
```

스마트 캐스트 : 코틀린에서는 타입 검사와 캐스트가 한 연산자에 의해 이루어진다.

어떤 객체의 타입을 검사했고 객체가 그 타입에 속한다면 해당 타입의 메소드나 필드 등의 멤버를 별도의 캐스트 없이 사용할 수 있다.
```kt
if (value is String)
    println(value.toUpperCase())
```
Note ) 

단, 스마트 캐스트는 변수의 타입을 검사한 다음 변경되지 않음을 보장할 수 있는 경우에만 동작한다. 

따라서 ``kt val``이면서 커스텀 접근자를 사용하지 않는 경우에만 동작한다.
``kt var``이면 null check/type check 이후 바로 변수를 사용하더라도 스마트 캐스트가 동작하지 않는데, 이는 바로 다음 코드에서 이 변수를 사용하더라도, 멀티 스레딩 환경에서는 변수가 변경되지 않음을 보장할 수 없기 때문이다.

원래 널이 될 수 있는 타입(``kt bar?``)은 ``kt .``으로 메소드를 호출할 수 없고(널 체크 포함으로 정의된 확장 함수 제외), 널이 될 수 없는 타입의 변수에 대입할 수 없는 등 제약 조건을 가지고 있다.

그러나 스마트 캐스트가 작동할 수 있는 조건을 만족하는 변수에 대해서 널 체크를 수행하고 나면 컴파일러가 그 사실을 기억해두고 ``kt null``이 아님이 확실한 영역에서는 해당 값을 널이 될 수 없는 타입의 값처럼 사용할 수 있다.

한 예로 ``kt if`` 또는 ``kt ?:``에 ``kt return``이 포함되어 있으면 이후의 코드는 실행되지 않는 것이 확실하기 때문에 스마트 캐스트가 동작한다. 그러나 ``kt return``이 포함되어 있지 않으면 프로그래머의 처리에 따라 ``kt null``인 상태로 이후 코드가 실행될 수도 있기 때문에 스마트 캐스트가 동작하지 않는다.


명시적 형변환

```kt
val n = e as Num
```

이런 식으로 사용하면 쓸데 없는 변수를 선언하지 않아도 돼서 편리한 경우가 있다.
```kt
(mainView as RelativeLayout).gravity
```

try-catch-finally

``kt try``도 식이기 때문에 ``kt try`` 실행 결과를 변수에 대입할 수 있다.

```kt

fun readNumber(reader: BufferedReader) {

    val number = try {

        Integer.parseInt(reader.readLine())

    } catch (e: NumberFormatException) {

        // return  여기서 return해버리면 val number 이후 문장이 실행이 안된다.

        null

    }

    println(number)

}

```


문자열 템플릿 ( string template )

 자바의 문자열 접합 연산( `` +``) 와 동일한 기능이다.
```kt
"Hello, $"
```
`` {}`` 내부는 문장이 아니라 식(expression)이다. 그래서 `` {}`` 내부에 다른 식과 문, `` "``, 또 다른 문자열 템플릿을 적어줄 수 있다.
```kt
"Hello, $!"
```
변수 이름만 사용하는 경우 `` {}``로 감싸지 않고 바로 ``kt $name``으로 사용할 수 있지만,  이런 경우에도 `` {}``로 감싸주는게 좋다. 정규식 패턴 매칭이 용이하며 가독성에도 도움이 되기 때문.

+ 유니코드 입력은 ``kt "\u2103"``

expression body : 한 줄 함수

```kt
fun max(a: Int, b: Int): = if (a > b) a else b
```
이렇게 한 줄로 작성된 함수를 식이 본문인 함수(expression body)라고 부른다. 반대는 블록이 본문인 함수(block body).
expression body에 `` =``를 사용하는 것은 함수형 개념을 잘 표현하기 때문인 것 같다.


```kt
fun expressionBody(i: Int) = when (i%2) {
    0 -> "i is $"
    else -> {
        println("else")
        "i is odd"
    }
}

fun blockBody(i: Int): String {
    when (i%2) {
        0 -> return "i is $"
        else -> {
            println("else")
            return "i is odd"
        }
    }
}
```
  • expression body는 알아서 타입 추론이 들어가기 때문에 리턴 타입을 지정하지 않아도 된다.
  • expression body로 작성하는 경우 ``kt return``을 적어서는 안된다.
  • expression body 내부에서 다시 `` {}``를 사용하는 경우, 블록의 맨 마지막 식이 반환값이 된다.
    Note ) 블록의 마지막 식이 블록의 결과라는 규칙은 블록이 값을 만들어내야 하는 경우 항상 성립한다.
  • block body로 작성하는 경우 반드시 ``kt return`` 문이 필요하다.
  • block body로 작성했는데 ``kt return``을 빼먹는 경우 ``kt kotlin.Unit``을 리턴하게 된다.

비트 연산자

``kt Int, Long`` 타입에만 사용할 수 있다.

```kt

x.shl(y)    : <<

x.shr(y)    : >>

x.ushr(y)   : >>>

x.and(y)    : &

x.or(y)     : |

x.xor(y)    : ~

x.inv()     : !

```