본문 바로가기

프로그래밍언어/Kotlin

[Kotlin] 튜토리얼 따라가기 (3) (Functions)

반응형

1. Functions

fun sum(x: Int, y: Int): Int {
    return x + y
}

fun main() {
    println(sum(1, 2))
    // 3
}

 

코틀린에서는 fun 키워드를 사용하여 함수를 선언한다. 매개변수는 타입과 함께 () 괄호 안에 선언되고, 함수 본문은 {} 안에 작성된다. 함수의 반환 타입은 함수 선언부의 매개변수 괄호 다음에 정의된다.

2. Named arguments

코틀린은 함수를 호출할 때 매개변수의 이름을 지정하여 인자를 입력할 수 있다. 이를 named argument 라고 하며, 이때는 매개변수의 순서와 상관없이 지정한 매개변수로 인자가 입력된다.

 

fun printMessageWithPrefix(message: String, prefix: String) {
    println("[$prefix] $message")
}

fun main() {
    // Uses named arguments with swapped parameter order
    printMessageWithPrefix(prefix = "Log", message = "Hello")
    // [Log] Hello
}

3. Default parameter values

함수를 정의할 때 매개변수의 기본값을 지정할 수 있다. 매개변수로 값이 입력되지 않더라고 기본값을 사용하여 함수가 실행될 수 있다.

 

//Functioncalledwithbothparameters
printMessageWithPrefix("Hello","Log")
//[Log]Hello

//Functioncalledonlywithmessageparameter
printMessageWithPrefix("Hello")
//[Info]Hello

printMessageWithPrefix(prefix="Log",message="Hello")
//[Log]Hello

4. Functions without return

코틀린에서 반환값이 없는 함수의 반환 타입은 Unit 이다. Unit 은 자바의 void 와 같은 의미로 함수에서 따로 반환 타입을 선언하지 않아도 된다.

 

fun printMessage(message: String) {
    println(message)
    // `return Unit` or `return` is optional
}

fun main() {
    printMessage("Hello")
    // Hello
}

5. Single-expression functions

fun sum (x: Int, y: Int): Int {
	return x + y
}

fun sumShort (x:Int, y:Int): Int = x + y

 

간단한 함수의 경우 single-expression function 으로 구현할 수 있다. 위의 sum() 함수에서 {} 괄호를 제외하고 = 연산자를 이용하여 sumShort() 처럼 간단하게 구현할 수 있다.

4. Lambda expressions

람다식을 이용하여 함수를 더 간결하게 표현할 수 있다.

 

fun uppercaseString(text: String): String {
    return text.uppercase()
}
fun main() {
    println(uppercaseString("hello"))
    // HELLO

   println({ text: String -> text.uppercase() }("hello"))
}

 

위의 예제에서 uppercaseString() 함수를 람다식으로 간단하게 작성했다.

 

{param1: type, param2: type, ... -> function_body}

 

람다식은 {} 괄호 안에 정의된다. 파라미터들을 선언하고 -> 연산자 이후에 함수 로직을 작성한다.

- Assign to variable

람다식은 아래 예제와 같이 함수에 할당하여 재사용이 가능하다.

 

fun main() {
    val upperCaseString = { text: String -> text.uppercase() }
    println(upperCaseString("hello"))
    // HELLO
}

- Pass to another function

val numbers = listOf(1, -2, 3, -4, 5, -6)
val positives = numbers.filter { x -> x > 0 }
val negatives = numbers.filter { x -> x < 0 }

println(positives)
// [1, 3, 5]
println(negatives)
// [-2, -4, -6]

 

위의 예제와 같이 함수의 인자로 람다식을 넣어서 사용할 수 도 있다. filter() 함수는 인자로 입력된 람다식을 조건문으로 사용하여 numbers 의 요소들을 필터링한다. map() 함수에서도 이와같이 사용할 수 있다.

 

※ 만약 람다식이 유일한 인자라면, 위의 에제와 같이 함수 호출 시에 () 괄호를 제외하고 바로 람다식을 인자로 입력할 수 있다.
이 부분은 뒤의 trailing lambda 에서 다시 정리한다.

- Function types

람다식의 함수 타입을 명시적으로 표현하기 위해서 다음 예제에서와 같이 () 괄호와 -> 기호를 사용할 수 있다.

 

val upperCaseString: (String) -> String = { text -> text.uppercase() }

 

위의 예제의 upperCaseString 에 입력된 람다식은 String 타입의 인자를 받아서 String 타입의 값을 반환한다.

- Return from a function

함수의 반환값으로 람다식을 사용할 수 있다. 이 경우에 컴파일러가 람다식이 어떤 타입을 반환하는지 알기 위해서 함수 타입을 선언해주어야 한다.

 

fun toSeconds(time: String): (Int) -> Int = when (time) {
    "hour" -> { value -> value * 60 * 60 }
    "minute" -> { value -> value * 60 }
    "second" -> { value -> value }
    else -> { value -> value }
}

 

위 예제에서 toSeconds() 함수는 (Int) -> Int 타입을 가진다. 해당 함수는 모든 경우에 Int 를 입력받아 Int 를 반환하는 람다식을 반환한다.

- Invoke separately

println({ text: String -> text.uppercase() }("hello"))
// HELLO

 

위의 예제와 같이 람다식 바로 뒤에 () 괄호와 인자를 입력하여 바로 람다식을 실행할 수 있다.

- Trailing lambdas

함수를 호출할 때, 함수의 인자로 들어가는 값이 람다식 뿐이거나 마지막 인자가 람다식인 경우 람다식은 () 괄호 없이 호출할 수 있다.

 

println(listOf(1, 2, 3).filter {x -> x > 0})

println(listOf(1, 2, 3).fold(0) { x, item -> x + item })

 

위의 예제에서 첫번째 구문은 이전에도 봤던 filter() 함수이다. filter() 함수의 인자로 람다식만 사용되기 때문에 이때는 () 괄호를 생략했다. 두번째 구문은 fold() 함수를 사용하고 있는데, 인자로 0 과 람다식을 사용하고 있다. 이때 람다식이 마지막 인자이기 때문에 0 () 괄호 사이에 입력하고 람다식은 () 괄호 바깥에 작성하였다.

 

[Reference]

- https://kotlinlang.org/docs/kotlin-tour-functions.html#lambda-expressions-practice

 

Functions | Kotlin

 

kotlinlang.org

 

반응형