Void and Never
Void has exactly one value, the keyword literal void, the way true and false are the values of Bool; Never has no value at all and converts to every type, which is why panic fits into any expression.
Diese Seite gibt es noch nicht auf Deutsch, deshalb steht sie hier auf Englisch. Zur englischen Seite
Void and Never sit at opposite ends of "how many values does this type have": Void has exactly one, written
void, and Never has none at all. A function without a result type returns Void; panic, return, break and
continue all have type Never.
Example#
fn setUp(): Void {
print "ready"
}
fn start(): Void {
setUp()
void
}
fn fail(message: String): Never {
panic message
}
fn firstOf(values: List<Int>): Int {
values.first() ?? fail("empty")
}
start()
print firstOf([1, 2, 3])Syntax#
fn f(): Void { ... } the same as fn f() { ... }: no result type means Void
void the one value of Void
fn f(): Never { ... } a function that never returns normallyRules#
Voidhas exactly one value, the keyword literalvoid, the waytrueandfalseare the values ofBool. A function without a result type returnsVoid, and a block that ends in a statement has the valuevoid.Voidis a type, and writing the type name where a value is expected is an error. The value is the lowercase keywordvoid; the uppercaseVoidnames the type and is never itself a value.Kompiliert nichtconst x = Void // error: `Void` is a type, not a value: its one value is written `void`Neveris the type of an expression that does not return:panic,return,break,continue. It has no value at all, which is why an expression of typeNeverfits into any context that expects a value.A
loopwithout abreakis the one statement with that type: nothing after it is reached, and a function whose whole body is one needs no other result. With abreakit isVoidlike every other loop. See Loops.fn serve(): Int { loop { print "waiting" } }Neverconverts to every type.values.first() ?? fail("empty")type checks as the element type ofvalues, becausefail'sNeverresult converts to whatever the other side of??needs.An expression statement has to have type
VoidorNever, unless the call has avarreceiver or avarargument.setUp()above is a statement because it returnsVoid; a call that returns something else and is never used is a compile error (see Bindings, rule 8).Void'sShowtext isvoid, the same word the literal is written with.print setUp()printsvoid, the same as printing the literal directly would.
What this is not#
Void is not the absence of a value the way Option.None is. Void always has its one value, void; there is
nothing to be absent. A function that may or may not produce a value returns Value?, not Void.
fn logged(): Void {
print "done"
}
logged()fn logged(): Void {
print "done"
}
const result = Void
print result
// error: `Void` is a type, not a value: its one value is written `void`Never is not Void with a stricter name. Void is a real value a caller receives; Never is a promise that
the call never returns to its caller at all. A function that sometimes returns and sometimes panics is typed by what
it returns when it does, not by Never.