[Kotlin] 함수 선언 및 사용 방법과 Unit, Nothing, Any
자바에선 메서드 이름 앞에 public, private 등 접근 제어자와 void, int 등 메서드가 리턴하는 값의 자료형을 명시한다.
public void를 갖는 메서드라면 어떤 클래스에서도 접근 가능한 리턴값이 없는 메서드를 말하고, private int를 갖는 메서드라면 해당 클래스에서만 사용 가능하고 리턴값으로 정수값을 리턴하는 메서드를 말한다.
코틀린에서도 private 등의 접근 제어자를 사용할 수 있지만 그 뒤에 붙는 용어가 "fun"이어야 한다. 아래는 코틀린에서 메서드를 사용하는 예시와 자바에서 메서드를 사용하는 예시다.
class Foo {
// 아무 값도 반환하지 않는 함수
fun foo(): Unit {
//
}
// 정수값을 반환하는 함수
private fun bar(): Int {
return 0
}
}
public class JavaFoo {
// 아무 값도 반환하지 않는 메서드
private void foo() {
//
}
// 정수값을 리턴하는 메서드
public int bar() {
return 0;
}
}
참고로 자바에서는 메서드란 단어를 많이 사용하지만 코틀린에서는 함수라는 말을 사용한다. 애초에 fun이 function(함수)의 줄임말이다. 그러나 표기법만 조금 다를 뿐이고 둘의 역할은 동일하다.
또한 코틀린에서 Unit은 하나의 타입인데 함수 자체를 의미한다. 자바의 void와 비슷하다고 보면 되는데, Unit 타입을 리턴하는 함수는 아래처럼 선언할 때 리턴 타입을 생략할 수 있다.
class Foo {
// 아무 값도 반환하지 않는 함수
fun foo() { // Unit을 붙이지 않아도 사용할 수 있다
//
}
// 정수값을 반환하는 함수
private fun bar(): Int {
return 0
}
}
만든 함수를 호출하는 방법은 "클래스명()" 뒤에 점(.)을 붙여 호출하면 된다.
class Foo {
// 아무 값도 반환하지 않는 함수
fun foo() { // Unit을 사용하지 않아도 사용할 수 있다
println("foo() 호출")
}
// 정수값을 반환하는 함수
fun bar(): Int {
return 0
}
}
fun main() {
Foo().foo()
// val a: Int = Foo().bar()
val a = Foo().bar()
println("a : $a")
}
// >> foo() 호출
// >> a : 0
main()에서 foo()를 호출할 경우 foo() 안에 써둔 println()이 호출되고, bar()을 호출할 경우 int 형태의 리턴값을 갖기 때문에 변수를 하나 선언해줘야 한다. 이 때 값을 담을 변수에 Int를 붙여도 되고 안 붙여도 되는데, 코틀린은 타입을 명시하지 않아도 변수에 할당된 값의 형태로 어떤 자료형을 갖는지 추론하는 타입 추론 기능이 있기 때문이다.
위의 소스코드를 실행하면 맨 밑의 주석에 적어놓은 결과대로 출력되는 걸 확인할 수 있다.
또한 자바의 void와 유사한 역할을 하는 게 Unit 타입이라고 말했는데, Unit 타입 말고도 Any, Nothing이라는 특수한 타입이 있다. 이 2가지를 정리하고 포스팅을 마무리한다.
Any
Any는 사전적으로 "아무것도, 무엇이든지" 라는 뜻을 갖고 있는 만큼 Any는 자바의 Object와 같은 개념이다.
즉 코틀린에 존재하는 모든 타입은 Any를 상속한다.
fun main() {
val hi: Any = "안녕"
val one: Any = 1
val decimal: Any = 0.5
println("hi : $hi")
println("one : $one")
println("decimal : $decimal")
}
// hi : 안녕
// one : 1
// decimal : 0.5
"안녕"이란 문자열은 본래 String 타입이지만 코틀린의 모든 타입은 Any를 상속하기 때문에, 서브 클래스의 객체는 부모 클래스에 대입이 가능하다는 문법적 특징을 적용받는다. 그래서 String 또한 Any 타입에 대입할 수 있다.
인텔리제이를 사용한다면 Any를 Ctrl + 좌클릭하면 아래와 같은 자바독 주석을 볼 수 있다.
The root of the Kotlin class hierarchy. Every Kotlin class has Any as a superclass
Kotlin 클래스 계층 구조의 루트입니다. 모든 Kotlin 클래스에는 슈퍼클래스로 Any가 있습니다
Nothing
Nothing은 "아무것도(아니다, 없다), 아무것도 아닌 것"이라는 사전적 정의를 가진 단어다. 그래서 코틀린에서도 Nothing이 붙는다면 어떤 값도 포함하지 않는 타입이라는 걸 뜻하며, 코드 실행 흐름이 도착할 수 없는 영역을 나타내기 위한 특수 타입으로 사용된다. 이런 성질 때문에 예외를 던질 함수 유형을 정의하는 데 사용된다.
Any에서와 마찬가지로 Ctrl + 좌클릭으로 Nothing을 클릭하면 private constructor가 정의되어 있기 때문에 객체를 만들 수 없고 생성자를 통한 접근도 불가능하다.
아래는 Nothing을 사용하는 예시다
class Foo {
fun iAmAlwaysThrowException(): Nothing = throw Exception("난 항상 예외를 던져요")
}
fun main() {
Foo().iAmAlwaysThrowException()
}
위 코드를 실행하면 인텔리제이 기준으로 아래와 같은 결과가 출력된다.