Zig Fn
Functions are an important tool in programming languages for organizing code and implementing logic.
Functions are a crucial means of structuring code; using them appropriately can enhance both readability and reusability.
In practical programming, you can define various functions as needed to achieve specific functionalities.
Zig functions are defined using the `fn` keyword.
### Basic Syntax
In Zig, the basic syntax for defining a function is as follows:
```zig
fn functionName(parameter_list) return_type {
// Function body
}
For example, let's define a simple function called `printHello` that prints "Hello, World!":
## Example
```zig
const std = @import("std");
pub fn main() void {
printHello();
}
fn printHello() void {
std.debug.print("Hello, World!n", .{});
}
After compilation, the output will be:
Hello, World!
### Parameter Passing
Functions can accept parameters, which can be values of various types.
Parameters are listed when defining the function and passed to the function upon invocation. For instance:
## Example
```zig
const std = @import("std");
pub fn main() void {
greet("Alice");
}
fn greet(name: []const u8) void {
std.debug.print("Hello, {s}!n", .{name}); // Use the {s} format specifier to print a string slice
}
The output after compilation will be:
Hello, Alice!
### Return Values
Functions can return values, with the return type specified in the function definition using the `return` keyword.
For example, let's define a function that calculates the sum of two integers:
## Example
```zig
const std = @import("std");
pub fn main() void {
const result = add(3, 5);
std.debug.print("3 + 5 = {}n", .{result});
}
fn add(a: i32, b: i32) i32 {
return a + b;
}
The output after compilation will be:
3 + 5 = 8
### Recursion
Functions can call themselves, known as recursive calls.
For example, let's define a recursive function that computes factorials:
## Example
```zig
const std = @import("std");
pub fn main() void {
const result = factorial(5);
std.debug.print("5! = {}n", .{result});
}
fn factorial(n: i32) i32 {
if (n == 0) {
return 1;
} else {
return n * factorial(n - 1);
}
}
The output after compilation will be:
5! = 120
### Function Overloading
Zig does not support traditional function overloading (i.e., multiple functions with the same name but different parameter lists).
However, Zig provides generic functions, allowing you to achieve effects similar to function overloading by using compile-time constant arguments. For example:
## Example
```zig
const std = @import("std");
pub fn main() void {
printValue(i32, 5); // Explicitly specify type as i32
printValue([]const u8, "Hello"); // Explicitly specify type as []const u8
}
```zig
fn printValue(comptime T: type, value: T) void {
std.debug.print("{any}n", .{value}); // Use {any} to handle values of different types
}
In this example, the `printValue` function can accept arguments of any type and print them accordingly.
The output after compilation will be:
5{ 72, 101, 108, 108, 111 }
### Inline Functions
Inline functions involve directly inserting the function's code into the calling location during compilation, thereby avoiding the overhead of a function call.
In Zig, you can use the `inline` keyword to define inline functions. For example:
## Example
```zig
const std = @import("std");
// Define an inline function
inline fn square(x: i32) i32 {
return x * x;
}
pub fn main() void {
const result = square(5); // The inline function's code is inserted at the call site
std.debug.print("Square of 5 is {}n", .{result});
}
In this case, the `square` function is defined as an inline function, and the compiler inserts its code directly at the call point.
The output after compilation will be:
Square of 5 is 25
YouTip