본문 바로가기

공부방/Kotlin

코틀린에서 함수를 다루는 방법

함수 선언 문법


코틀린에서는 함수를 어떻게 선언하는지에 대해서 알아봅시다.

두 변수 a와 b의 크기를 확인하고 큰 값을 return해주는 함수입니다.

같은 기능을 자바로 구현한 결과와 코틀린으로 구현한 결과를 비교해보겠습니다.

 

[Java]

평범한 자바 코드입니다.

이러한 코드를 코틀린으로 구현하다면 어떻게 해야 할까요?

 

public class Lec08Main {
	public int max(int a, int b) {
		if (a > b) {
			return a;
		}
		return b;
	}
}

 

[Kotlin]

접근제한자 명시해 놓지 않으면 기본으로 public 접근제한자가 적용됩니다.

반환 타입도 Unit 인 경우는 생략 가능합니다.

 

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

 

[Kotlin] block => = 

함수가 하나의 결과 값이면 block 대신 = 을 사용할 수 있습니다. (return은 없어짐)

 

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

 

[Kotlin] return 생략

return 타입은 추론이 가능하기 때문에 생략 가능합니다.

 

중괄호 {} 대신 = 을 사용하였을 때만 생략이 가능합니다.

 

 

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

 

[Kotlin] 코드 한줄로 변경

if - else 문을 한 줄로 변경할 수 있습니다.

 

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

 

[Kotlin] if문 중괄호 생략

중괄호까지 생략하면서 코드가 완성되었습니다.

 

fun max(a: Int, b: Int) = if (a > b) a else b

 

 

default parameter


코틀린에는 default parameter가 존재합니다.

springboot에서 request param을 사용할 때 default parameter를 지정하는 것과 동일한 기능이라고 보시면 됩니다.

자바 일반 함수에서는 default parameter가 존재하지 않습니다.

 

[Java]

세개의 매개변수를 받는 함수입니다.

 

package lec08;

public class Lec08Main {
	/**
	 *
	 * @param str 문자열
	 * @param num 몇번 출력할 지
	 * @param useNewLine 개행 여부
	 */
	public void repeat(String str, int num, boolean useNewLine) {
		for (int i = 0; i < num; i++) {
			if (useNewLine) {
				System.out.println(str);
			} else {
				System.out.println(str);
			}
		}
	}
}

 

useNewLine 이라는 매개변수가 일반적으로 ture 값을 사용한다면 아래와 같이 overload 하여 함수를 사용할 수 있습니다.

 

 

public class Lec08Main {
	// 매번 true를 인자로 주기 귀찮기 때문에 true를 default로 주는 메서드를 만들어서 사용합니다.
	public void repeat(String str, int num) {
		repeat(str, num, true);
	}
}

 

[Kotlin] 

기본적으로 사용하는 매개변수가 많을 수록 overload 함수가 많아지는 케이스가 생길 수 있습니다.

이러한 문제를 해결하기 위해 코틀린에서는 default parameter를 지정할 수 있습니다.

아래와 같이 말이죠

 

fun repeat(
	str: String, 
	num: Int = 3, 
	useNewLine: Boolean = true) {
	for (i in 1..num) {
		if (useNewLine) {
			println(str)
		} else {
			print(str)
		}
	}
}

 

named argument


default parameter 와 이어지는 내용입니다.

이제 default parameter를 지정해서 편리하게 사용할 수 있게 되었습니다.

두가지 매개변수가 default parameter를 가지고 있습니다.

 

그러나 우리는 useNewLine이라는 변수만 값을 지정해 주고 싶습니다.

이럴때는 어떻게 해야 할까요?

 

[Kotlin]

바로 named argument를 사용하면 되는 것입니다.

매개변수 이름을 지정해서 값을 할당할 수 있는 기능입니다.

 

fun main() {
	repeat(str = "Helloworld", useNewLine = true)
}

fun repeat(
	str: String,
	num: Int = 3,
	useNewLine: Boolean = false) {
	for (i in 1..num) {
		if (useNewLine) {
			println(str)
		} else {
			print(str)
		}
	}
}

 

default parameter가 존재하는 경우 builder를 직접 만들지 않고 builder의 장점을 가지게 됩니다.

 

그러나 Kotlin에서 Java 함수를 가져와서 사용하는 경우에는 named argument를 사용할 수 없습니다.

자바는 바이트코드로 변경될 때 인자 이름을 가지고 있지 않기 때문에 사용할 수 없습니다.

 

같은 타입의 여러 파라미터 받기 (가변인자)


[Java]

자바에서는 가변인자를 받아들일 수 있습니다.

코틀린에서는 어떻게 구현할 수 있을까요?

 

public class Lec07Main {
	public static void main(String[] args) {
		printAll("A", "B", "C");
		// 자바는 배열도 바로 넣을 수 있다.
		String[] strings = {"A","B","C"};
		printAll(strings);
	}

  public static void printAll(String... strings) {
	  for (String string : strings) {
		  System.out.println(string);
	  }
  }
}

 

[Kotlin]

가변인자를 사용할 때는 vararg 문법을 사용해야 하며, 

배열을 넣을떄는 * 를 붙여줘야합니다. (spread 연산자)

 

fun main() {
	printAll("A", "B", "C")
	val array = arrayOf("A", "B", "C")
	// spread 연산자를 붙여줘야 한다. (*)
	printAll(*array)
}


fun printAll(vararg strings: String) {
	for (string in strings) {
		println(string)
	}
}