Skip to content

Parameters and Return Values

Functions communicate through parameters and return values.

Functions communicate through parameters and return values.

Here is a function with one parameter and one return value:

fn increment(x: i32) i32 {
    return x + 1;
}

The parameter is declared inside the parentheses:

x: i32

x is the parameter name. i32 is the parameter type.

The caller passes a value to the function:

const n = increment(10);

Inside the function, x receives the value 10.

Parameters are local to the function. They exist only while the function runs.

Functions may have many parameters:

fn add(a: i32, b: i32) i32 {
    return a + b;
}

The call:

const x = add(3, 4);

passes 3 into a and 4 into b.

Arguments are matched by position.

The types must agree:

const x = add(3, 4);

but:

const x = add(true, 4);

is an error.

Zig checks argument types at compile time.

A function may return any type:

fn isPositive(x: i32) bool {
    return x > 0;
}

Here the return type is bool.

Another example returns a floating-point value:

fn half(x: f64) f64 {
    return x / 2.0;
}

The return type appears after the parameter list:

fn half(x: f64) f64

The return statement ends the function immediately:

fn sign(x: i32) i32 {
    if (x < 0) {
        return -1;
    }

    if (x > 0) {
        return 1;
    }

    return 0;
}

Each branch returns a value of the declared return type.

Functions that return nothing use void:

fn newline() void {
    std.debug.print("\n", .{});
}

A void function may use:

return;

or omit the return statement entirely.

Return values are expressions. The returned value may come from a calculation:

fn area(width: i32, height: i32) i32 {
    return width * height;
}

or from another function call:

fn square(x: i32) i32 {
    return x * x;
}

fn fourthPower(x: i32) i32 {
    return square(square(x));
}

Functions may also return compound values.

This function returns a struct:

const Point = struct {
    x: i32,
    y: i32,
};

fn makePoint(x: i32, y: i32) Point {
    return Point{
        .x = x,
        .y = y,
    };
}

The caller receives the returned value as a normal expression:

const p = makePoint(3, 4);

Parameters themselves are immutable. This is important.

The following is illegal:

fn f(x: i32) void {
    x = 10;
}

because parameters behave like const.

If a local mutable value is needed, declare a new variable:

fn f(x: i32) i32 {
    var y = x;
    y += 1;
    return y;
}

This keeps function inputs predictable.

A function signature consists of the function name, parameter types, and return type:

fn add(a: i32, b: i32) i32

The signature describes how the function is used.

Exercise 4-5. Write a function minimum that returns the smaller of two integers.

Exercise 4-6. Write a function clamp that limits a value to a given range.

Exercise 4-7. Write a function average that takes two f64 values and returns their average.

Exercise 4-8. Why are function parameters immutable in Zig?