Kotlin

자바는 재사용 가능한 가장 작은 단위가 클래스인 반면,
코틀린은 재사용 가능한 가장 작은 단위가 클래스 없이도 사용 가능한 단독 함수 이다.

 

1. 함수 생성

1.1 KISS 함수

  • 코틀린은 키스😘 (KISS, Keep It Simple, Sutpid) 원칙을 준수한다.
  • 함수 정의는 fun 키워드로 시작한다.
// kiss.kts

fun greet() = "Hello"
println(greet())

 

1.2 리턴타입과 타입 추론

  • 위의 greet 함수는 문자열을 리턴하고 리턴 타입이 없지만 블록 바디 {} 가 없는 함수에 대해 타입 추론을 해준다.
  • 하지만 다른 개발자가 쉽게 알아볼 수 있게 타입을 넣어주자
fun greet(): String = "Hello"
println(greet())

 

1.3 Unit 타입

  • 코틀린은 Unit 이라는 타입을 사용하며, 자바의 void 와 대응된다.
    • 아무런 정보를 갖지 않는 싱글톤인 Unit 에서 유래했다고 한다.
  • Unit 타입은 toString(), equals(), hashCode() 메소드를 가지고 있다.

 

// specifyunit.kts

fun sayHello(): Unit = println("Well, Hello")
val message: Unit = sayHello()
println("The result of sayHello is $message")

 

아래는 결과

 

$ kotlinc-jvm -script specifyunit.kts
Well, Hello
The result of sayHello is kotlin.Unit

 

kotlin.unit 이라는 클래스 이름만 리턴한다.

 

1.4 파라미터 정의

  • "candidate(후보) : Type" 형태의 문법을 사용한다.
  • 여러 개의 파라미터가 있는 경우 콤마(,) 로 구분하여 추가한다.
    • fun greet(name: String[, val2: String]): String = "Hello $name"

1.5 블록 바디로 만든 함수

  • {}블록을 사용해서 바디를 만든다.
  • 리턴 타입이 없다면, Unit 으로 추론된다.
fun min(numbers: IntArray): Int {
	var small = Int.MAX_VALUE
	for (number in numbers) {
		small = if (number < small) number else small
	}

	return small
}

println(min(intArrayOf(1, 5, 2, 12, 7, 3)))

 

해당 함수는 가장 작은 수를 출력한다.

 


2. 기본 인자와 명시적 인자

2.1 기본 인자(Default Argument)를 통한 함수 변경

  • 오버로딩(Overloading) 을 통한 기본 인자(Argument) 설정이 가능하다.
# defaultarguments.kts

fun greet(name: String, msg: String = "Hello"): String = "$msg $name"
println(greet("Eve")) //Hello Eve
println(greet("Eve", "Howdy")) //Howdy Eve

 

기본 인자는 후위에 둔다. fun greet(msg: String = "Hello", name: String) 로도 실행이 가능하지만, 일반 인자는 항상 필요하기 때문에 기본 인자를 앞에 두면 의미가 없다.

 

# defaultarguments.kts

fun greet(name: String, msg: String = "Hi ${name.length}"): String = "$msg $name"
println(greet("Scott", "Howdy")) //Howdy Scott
println(greet("Scott")) //Hi 5 Scott

 

이런 식으로도 사용 가능하다.

 

2.2 명시적 인자(Named Argument)를 이용한 가독성 향상

  • 코틀린에서는 사용될 인자를 정확하게 표기하여 호출이 가능하다.
fun createPerson(name: String, birth: Int = 1, height: Int, weight: Int) {
    println("$name $birth $height $weight")
}

createPerson("Jake", birth = 2010, height = 43, weight = 152) // Jake 2010 43 152
createPerson(birth = 2010, height = 43, weight = 152, name = "Jake") // Jake 2010 43 152
createPerson(height = 43, weight = 152, name = "Jake") // Jake 1 43 152

 

이런식으로 사용하여 가독성을 향상시킬 수 있다.

 


3. 다중인자와 스프레드

  • 숫자 배열을 인자로 받을 수 있다. 이때 사용하는 것이 vararg 이다.
  • 배열을 전달할땐 스프레드 연산자인 *(asterisk, 아스테리크) 연산자를 사용한다. (마치 포인터 같다.)
  • 기본 인자처럼 후위에 선언하는 것이 좋다.
fun max(vararg numbers: Int): Int {
	var large = Int.MIN_VALUE
	for (number in numbers) {
		large = if (number > large) number else large
	}

	return large
}

//println(max(1,2,3,4,5,6,7,8,10))

// var values = intArrayOf(12346,137,15347,254,72,10)
// println(max(*values))

println(max(*intArrayOf(10,1,2,3,5,20,31,60,29)))
println(max(*listOf(1, 4, 18, 12).toIntArray()))

 


4. 구조분해

  • 속성의 위치를 기반으로 구조분해가 가능하다.
  • _ (언더스코어) 를 통해 생략할 수 있다.
fun getFullName() = Triple("Trafalgar", "D.", "Water Law")

var result = getFullName()
println("${result.first} ${result.second} ${result.third}")

var (first, _, last) = getFullName()
println("$first $last")

var (_, middle) = getFullName()
println("$middle")

 

Triple 함수를 사용해보았다.