-
[Kotlin] Nothing, UnitKotlin/Types 2021. 8. 16. 15:28
인터넷의 여러 글들을 읽어봤지만 Nothing과 Unit의 차이에 대해 정확하게는 모르겠고 어떠한 식으로만 써야하는지에 대해서만 안것 같다. 이해를 위해 글의 순서가 뒤죽박죽일 수 있다.
Any는 모든 타입의 조상 타입
Nothing은 모든 타입의 서브 타입
Unit은 싱글톤 인스턴스로 자바의 void를 나타낸다.
함수가 리턴되지 않을 경우 Unit대신 Nothing을 쓰자.
Nothing은 모든 타입의 서브 타입
fun test(): 조상타입{ return 자손인스턴스 }
자손인스턴스는 조상타입으로 캐스팅 가능하기 때문에 컴파일 에러가 발생하지 않는다.
마찬가지로
코틀린에서 throw 표현식은 Nothing타입이다. Nothing은 모든 타입의 서브타입이기 때문에 어떠한 타입으로도 캐스팅 될 수 있다. String으로 캐스팅될 수 있기 때문에 메서드는 컴파일 에러가 발생하지 않는다.
마찬가지로 다음의 코드들도 문법상 문제가 없다.
Unit과 Nothing은 어떠한 차이가 있을까
자바의 예외를 던지는 메서드를 보자.
void reportError() { throw new RuntimeException(); }
코틀린으로 자바와 같은 메서드를 만들면 아래와 같이 된다.
fun reportError(): Unit { throw RuntimeException() }
위의 메서드를 좀더 코틀린 답게 사용하기 위해 코틀린에서는 Nothing이라는 타입을 제공한다.
fun reportError(): Nothing { throw RuntimeException() }
리턴타입을 생략하면 Unit으로 취급되기 때문에 리턴타입에 Nothing으로 사용하려면 꼭 명시적으로 써야한다.
위의 리턴타입이 Unit, Nothing인 두 메서드는 내부적으로는 같은 동작을 하기 때문에 리턴을 제외한 메서드 하나의 내부 동작만 보면 차이가 없어 보인다. 그렇다면 어떠한 차이가 있는 것인가
Unit은 리턴타입이 없지만 리턴 행위 자체는 한다-> 정상적으로 종료되었음을 알리는 것이고
Nothing은 리턴 행위 자체를 하지 않아서 정상적으로 종료가 되지 않았음을 알리는 것이다.
리턴타입이 Nothing이라는 것은 메서드가 리턴 행위 자체를 하지 않고 종료된다.
비정상 종료 -> 예외 또는 무한 루프가 동작할 경우 사용한다.
Unreachable code
Unit인 경우
var a= method()는 절대로 수행되지 않는다.
자바처럼 Unit을 리턴타입으로 지정한 경우 아무런 warning을 띄워주지 않는다.
Nothing인 경우
Nothing타입으로 지정하면 var a = method()는 절대 실행될 수 없는 코드라고 warning을 띄워준다.
Ternary operator
Unit인 경우
Elvis operator의 우변이 Unit타입이라 컴파일 에러가 발생한다.
따라서 아래와 비스무리처럼 밖에 사용할 수 밖에 없다.
Nothing인 경우
fail()메서드의 return 타입은 Nothing이다.
Nothing은 모든 타입은 서브 타입이다. 그렇기 때문에 var a: String으로 선언해도 문제가 없게 된다.
또한 fail()메서드가 호출될 경우 예외가 발생하게 되므로 println(a.length)는 항상 실행되지 않기 때문에
컴파일 에러가 발생하지 않는다.
Throw in a method that has a meaningful return type
자바의 경우
의미가 없는 return 타입이지만 꼭 써줘야 컴파일이 된다.
코틀린의 경우
reportError()의 리턴타입이 모든 타입의 서브타입인 Nothing이므로
exampleThree의 리턴타입 String지정은 문제가 없다.
이것과 같이....
'Kotlin > Types' 카테고리의 다른 글
[Kotlin] Array (0) 2021.12.16 [Kotlin] Type check and Type casts (0) 2021.08.13 [Kotlin] 코틀린 패키지 / .kt파일과 .java파일 (feat. top-level선언) (0) 2021.07.21 [Kotlin] val / const val (0) 2021.07.21 [Kotlin] 변수/자료형 (0) 2021.07.07