Declaring a function
fn declares a function with a mandatory parameter type on every parameter; the last expression of the body is the result, and a public function or a trait method must always spell out its return type.
Diese Seite gibt es noch nicht auf Deutsch, deshalb steht sie hier auf Englisch. Zur englischen Seite
fn declares a function. A parameter always carries its type, the last expression of the body is what the function
answers, and return leaves the function early with a value.
Example#
fn isOdd(n: Int): Bool {
if n == 0 { false } else { isEven(n - 1) }
}
fn isEven(n: Int): Bool {
if n == 0 { true } else { isOdd(n - 1) }
}
fn factorial(n: Int): Int {
if n <= 1 {
return 1
}
n * factorial(n - 1)
}
print isOdd(7)
print factorial(5)Syntax#
fn <name>[<type parameters>](<parameters>) [: <ReturnType>] {
<statement>*
<result expression>?
}Rules#
Every parameter has a written type.
fn, unlike a closure, never infers a parameter's type from how it is called.The result type may be left out on a function that is not
publicand is not a trait method. The compiler infers it from the body.fn double(x: Int) { x * 2 } print double(21)A
publicfunction or a trait method never infers its result type. Its signature is the only thing a caller in another package reads, so it has to be complete without the body.Kompiliert nichtpublic fn double(x: Int) { x * 2 } // error: A `public` function does not infer its result: declare it (`: Int64`)The last expression of the body is the result, and
returnleaves early with a value. A function whose body ends in a statement rather than an expression answersvoid, the one value ofVoid.A top-level
fnis hoisted to the top of its file. A function may call another one declared later in the same file, which is what makes mutual recursion possible there without a forward declaration. A localfn, nested inside another function, is not hoisted this way: it sees only its own parameters and the top level of its file (see What this is not), not a sibling localfndeclared next to it.fn ping(n: Int): Int { if n <= 0 { 0 } else { pong(n - 1) } } fn pong(n: Int): Int { if n <= 0 { 0 } else { ping(n - 1) } } print ping(4)
What this is not#
A local fn is not a closure. It captures nothing: it sees only its own parameters and the top level of its
file, exactly like a function declared outside any block. Write a closure when the code needs to reach into the
surrounding scope (see Closures).
fn makeAdder(step: Int): (Int) => Int {
{ value => value + step }
}
print makeAdder(3)(4)fn makeAdder(step: Int): (Int) => Int {
fn add(value: Int): Int {
value + step
}
add
}
// error: Cannot find `step` hereRelated#
- Arguments and labels - positional and labelled parameters, and the order they are written in.
- Closures - the one closure form, and what it captures instead.
- Bindings - the same
const/varsplit applies to a parameter.