본문 바로가기

Study/Kotlin Study

[Kotlin] 함수

+ 항공대학교 김철기 교수님의 객체 지향 프로그래밍 과목 내용를 정리한 글입니다.

Kotlin 함수의 예

import kotlin.math.PI // kotlin 패키지에서 PI 상수를 가져옴

fun circleArea(radius: Double): Double { // 함수의 정의
    return PI * radius * radius
}

fun main() {
    print("Enter radius: ")
    val radius = readLine()!!.toDouble()
    println("Circle area: ${circleArea(radius)}")
}

Kotlin 함수의 특징 (1)

- 파라미터의 타입은 항상 지정해야 한다.

fun circleArea(radius: Double): Double // O
fun circleArea(radius): Double // X

 

- 반환값이 없는 경우만 반환값의 타입을 생략할 수 있다.

(C의 void 함수 = Kotlin의 Unit 함수)

fun prompt(name: String) {
    println("*** Hello, $name! ***")
}
fun prompt(name: String): Unit { // 위 함수와 동일
    println("*** Hello, $name! ***")
}

Kotlin 함수의 특징 (2)

- 파라미터의 값은 수정이 불가능하다. (파라미터는 val변수의 특성을 갖는다.)

fun foo(bar: Int): Int {
    bar += 1 // Error
    return bar
}
fun foo(bar: Int): Int {
    val baz = bar + 1 // 새로운 변수에 할당하여 변경
    return bar
}

식 하나가 본문인 함수

- 함수형 언어에서 영향을 받았다.

 

- 식 하나로 표현이 가능한 함수의 경우 return을 생략하고 =로 함수 선언과 본문을 연결할 수 있다.

fun circleArea(radius: Double): Double = PI * radius * radius

- 식에서 반환값의 타입이 유추가 가능한 경우 반환 타입 생략이 가능하다. (타입 추론)

fun circleArea(radius: Double): = PI * radius * radius

함수의 호출

- 함수를 호출할 때 세 가지 형태가 모두 가능하며 동일한 의미이다.

fun rectangleArea(width: Double, height: Double) = width * height

fun main() {
    val w = readLine()!!.toDouble()
    val h = readLine()!!.toDouble()

    println(rectangleArea(w, h))
    println(rectangleArea(width = w, height = h))
    println(rectangleArea(height = h, width = w))
}

=> 즉, 파라미터의 이름으로 인자를 전달할 수 있다.


함수의 오버로딩

- 동일한 이름의 함수를 파라미터 타입의 변이에 따라 여러 버전으로 정의하는 프로그래밍

- 객체지향 연구자들이 주장한 개념으로 객체지향적 개념으로 분류한다.

- 다형성(polymorphism)의 일종이다. (형: 타입)

- 변수의 이름이 부족한 현상을 해결해준다.

// 두 함수를 동시에 정의 가능
fun readInt() = readLine()!!.toInt()
fun readInt(radix: Int) = readLine()!!.toInt(radix) // radix진법을 입력 받고 10진법으로 반환

fun main() {
    val num1 = readInt()
    val num2 = readInt(2)

    println("num1: $num1, num2: $num2")
}

함수 호출 시 오버로딩 해소 규칙

1. 파라미터의 개수와 타입을 기준으로 호출할 수 있는 모든 함수를 찾는다.

 

2. 덜 구체적인 함수를 제외한다. 어떤 함수의 파라미터 타입이 다른 함수에 비하여 포괄적일 경우 이를 제외한다. 이 과정을 하나의 함수가 남을 때까지 반복한다.

 

3. 하나가 남으면 해당 함수를 호출한다. 두 개 이상이 남으면 컴파일 에러가 발생한다.


함수 오버로딩의 예

fun mul(a: Int, b: Int) = a * b

fun mul(a:Int, b: Int, c: Int) = a * b * c

fun mul(s: String, n: Int) = s.repeat(n)

fun mul(o: Any, n: Int) = Array(n) {o}
// Array(n): 길이가 n인 배열 생성
// {o}: 각 요소를 o으로 채운다.

fun main() {
    println(mul(1, 2)) // 1번 함수 호출

    println(mul(1L, 2)) // 4번 함수 호출

    println(mul("O" as Any,3))  // 4번 함수 호출
    // 문자열 "O"를 상위 개념인 Any 타입으로 생각하고 호출 수행

    println(mul("O", 3)) // 3번 함수 호출

}

함수의 디폴트 파라미터

// 파라미터가 주어지지 않으면 자동으로 10을 파라미터로 갖는다.
fun readInt(radix: Int = 10) = readLine()!!.toInt(radix)

fun main() {
    val decimalInt = readInt()
    val decimalInt2 = readInt(10) // 위와 동일한 함수 호출이다.

    println("$decimalInt, $decimalInt2")
}

함수의 가시성

1. public 함수

- 프로젝트의 어디서나 해당 함수 호출이 가능하다.

- 가시성 선언이 없는 함수는 디폴트로 public 선언된다.

fun readInt(): Int = readLine()!!.toInt()
// 디폴트 public 가시성으로 정의

 

2. internal 함수

- 함께 컴파일되는 모듈 안에서만 호출이 가능하다.

internal fun readInt(): Int = readLine()!!.toInt()

 

3. private 함수

- 같은 파일 안에서만 호출이 가능하다.

private fun readInt(): Int = readLine()!!.toInt()

함수 내 함수

- 함수를 감싸는 블록에서만 호출이 가능하다.

  => 특정 함수내에서만 사용되는 함수를 다른 곳에서는 사용하지 않음을 나타낸다는 장점이 존재한다.

- 함수 내 변수에 접근이 가능하다.

  => 인자에 전달하지 않아도 되므로 오버헤드(복잡도)가 줄어든다. (인자 수가 줄어든다.)

fun main(args: Array<String>) {
    // String 배열 args 받아오기
    fun swap(i: Int, j: Int): String {
        val chars = args[0].toCharArray()
        // String 배열 args의 첫번째 문자열을 char 배열로 변환 후 chars에 저장

        val tmp = chars[i]
        // i 위치의 문자를 tmp에 저장

        chars[i] = chars[j]
        // chars의 i번째 문자를 chars의 j번째 문자로 변경

        return chars.concatToString()
        // char 배열로 변경되었던 chars를 다시 String로 변경하여 반환
    }
    println(swap(0, args[0].lastIndex))
    // swap 함수 호출
    // 주어진 문자열 args의 첫번째 문자열의 첫번째 문자를 마지막 문자로 바꾼후 출력
}

'Study > Kotlin Study' 카테고리의 다른 글

[Kotlin] 단순한 변수 이상인 프로퍼티  (0) 2023.09.17
[Kotlin] 널 가능성  (0) 2023.09.12
[Kotlin] 클래스 정의하기  (1) 2023.08.28
[Kotlin] 예외 처리  (0) 2023.08.25
[Kotlin] 루프 (반복문)  (2) 2023.08.24