skip to content

Unit & Nothing Return Types

Unit is the return type you can omit for side-effecting functions; Nothing is the return type of functions that never finish normally. Declaring a helper as returning Nothing is what makes the compiler treat a call to it as an exit, which affects definite assignment and smart casts.

part ofKotlinoverview, primer and where to startread it →
on this pageshow

questions

5

What is the Unit type in Kotlin, and how does it differ from Java's void? When can you omit it from a function signature?

level: juniorimportance: must knowfreq 75%

answer

  1. Unit = real type, one value, named Unit
  2. void is a keyword, Unit is a type
  3. Omit `: Unit` — it is inferred
  4. Unit fits generics: Function0<Unit>
  5. Lambda last expression ignored (Unit-coercion)

basics

~20 s

Unit is Kotlin's type for functions that do useful work but return no meaningful value. It is like Java's void, but it is a real type with one value. You can leave it out of the signature.

solid answer

~40 s

Unit is a real singleton type with exactly one value, also written Unit. A function with no declared return type returns Unit implicitly, so `fun log(s: String)` and `fun log(s: String): Unit { ... }` are identical. Unlike Java's `void` (which is not a real type and cannot be used as a generic argument), Unit is a normal type, so it can fill type parameters: `Function0<Unit>`, `List<Unit>`, or a `suspend () -> Unit` lambda. Because Unit is a value, the compiler implicitly returns it; you rarely write `return Unit` explicitly. In lambdas, the last expression's value is ignored when the expected return type is Unit (Unit-coercion), so a lambda body can end in any expression.

code

kotlin · 5 lines
kotlin
fun save(item: String) { /* returns Unit */ }

// Unit as a generic argument — impossible with Java void
val tasks: List<() -> Unit> = listOf({ println("a") }, { println("b") })
val result: Unit = save("x")  // valid: Unit is a value

go deeper

for a junior

Knows Unit means 'no meaningful return' and that it is omittable, roughly like void.

for a middle

Explains Unit is a real singleton type with one value and why that beats void for generics/lambdas.

for a senior

Discusses Unit-coercion in lambdas and JVM-level compilation to void for interop.

for a principal

Frames Unit as part of a uniform type system (everything is a value/type), contrasting language designs that special-case void.

## What Unit is `Unit` is an ordinary Kotlin type that has **exactly one instance**, also named `Unit` (it is declared `object Unit`). A function that performs an action but has nothing meaningful to give back returns `Unit`. ```kotlin fun greet(name: String): Unit { println("Hi, $name") // compiler inserts `return Unit` } // identical — the `: Unit` is omittable fun greet2(name: String) { println("Hi, $name") } ``` When you do not write a return type, the compiler infers `Unit`. So omitting it is the idiomatic style. ## Unit vs Java's `void` - Java's `void` is **not a type** — it is a keyword marking "no return." You cannot write `List<void>` or pass `void` as a generic argument. - `Unit` **is a type with a value**, so it works everywhere a type is expected: `Function0<Unit>`, `Callable<Unit>`, `suspend () -> Unit`. - This matters for generics and functional code. A higher-order function `fun <T> run(block: () -> T): T` can be called with a block returning `Unit`; with `void` that would be impossible. At the JVM bytecode level a Unit-returning Kotlin function compiles to a `void` method for interop, but in the Kotlin type system it is `Unit`. ## Unit-coercion in lambdas If the expected type of a lambda is `() -> Unit`, the value of its last expression is **discarded**, so the body may end with any expression: ```kotlin val action: () -> Unit = { 42 } // 42 is ignored; lambda returns Unit ``` ## When you can omit it - Always in a function declaration: leave off `: Unit`. - You almost never write `return Unit`; a bare `return` (or falling off the end) suffices. ## Key terms - **Singleton / object**: a type with a single shared instance. - **Type parameter / generic argument**: the `T` in `List<T>`; Unit can be one, `void` cannot.

  • Why can't you use Java's void as a generic type argument but you can use Unit?
    void is a keyword, not a type, so the type system has no object to substitute for a type parameter. Unit is a real type with a value, so it substitutes normally.
  • Does a Unit-returning Kotlin function compile to a Unit or void method on the JVM?
    To a `void` JVM method for clean Java interop; Unit exists only in the Kotlin type system.

Unit is like signing a delivery receipt: the action happened, and the single signature is the only 'value' that comes back.

saying these in an interview costs you the question

  • Saying Unit and void are exactly the same with no nuance
  • Claiming you must write `return Unit` explicitly
  • Thinking Unit can hold multiple distinct values
  • Believing Unit cannot be used as a generic argument
  • Confusing Unit (no value) with Nothing (no return)

context

open as a page

What is the Nothing type in Kotlin, and what does it mean for a function to be declared with return type Nothing?

level: middleimportance: must knowfreq 65%

basics

~10 s

Nothing is the type for code that never returns normally — it always throws, loops forever, or stops the program. A function returning Nothing tells the compiler the line after it is unreachable.

open as a page

Explain how a Nothing-returning function or `throw` enables expressions like `val x = a ?: error("...")` and why the compiler then treats following code as unreachable.

level: middleimportance: should knowfreq 55%

basics

~20 s

Because a throw or a Nothing function can stand in for any type, you can put it after Elvis (?:) to get a non-null value or bail out. The compiler knows that path can't continue, so code after it is dead.

open as a page

When should you explicitly declare a function's return type as Nothing, and what concrete benefits does that give callers versus declaring it Unit or omitting the type?

level: seniorimportance: should knowfreq 45%

basics

~20 s

Declare Nothing when a function never returns — it only throws or loops. This lets callers use it after Elvis, in when-branches, and as any value, and tells the compiler the code after it is dead.

open as a page

How do Unit and Nothing interact with type inference and generics — for example, the inferred type of `val x = null`, the result of `emptyList()`, and lambdas like `{ throw E() }`?

level: seniorimportance: nice to knowfreq 35%

basics

~20 s

Nothing is the type the compiler picks when an expression has no real value, like a lambda that only throws. null alone is Nothing?. The compiler then specializes these from context, and Unit is what value-less lambdas infer to.

open as a page