Structs
const std = @import("std");
const Punkt = struct {
x: f64,
y: f64 = 0, // Standardwert
fn abstand(self: Punkt) f64 {
return @sqrt(self.x * self.x + self.y * self.y);
}
fn verschiebe(self: *Punkt, dx: f64, dy: f64) void {
self.x += dx;
self.y += dy;
}
const ursprung = Punkt{ .x = 0 }; // Konstante im Struct
fn neu(x: f64, y: f64) Punkt { // "Konstruktor": normale Funktion
return .{ .x = x, .y = y };
}
};
const Farbe = enum { rot, gruen, blau };
const Form = union(enum) { // getaggte Union
kreis: f64,
rechteck: struct { b: f64, h: f64 },
fn flaeche(self: Form) f64 {
return switch (self) {
.kreis => |r| std.math.pi * r * r,
.rechteck => |r| r.b * r.h,
};
}
};
pub fn main() !void {
const out = std.io.getStdOut().writer();
var p = Punkt.neu(3, 4);
try out.print("{d} {d}\n", .{ p.abstand(), Punkt.ursprung.x });
p.verschiebe(1, 1);
try out.print("({d}, {d})\n", .{ p.x, p.y });
try out.print("{any}\n", .{p});
const f: Farbe = .gruen;
try out.print("{s} {d} {any}\n", .{ @tagName(f), @intFromEnum(f), f == .gruen });
switch (f) {
.rot => try out.print("R\n", .{}),
.gruen, .blau => try out.print("nicht rot\n", .{}),
}
const formen = [_]Form{ .{ .kreis = 1 }, .{ .rechteck = .{ .b = 3, .h = 4 } } };
for (formen) |form| try out.print("{d:.2}\n", .{form.flaeche()});
}5 0
(4, 5)
main.Punkt{ .x = 4e0, .y = 5e0 }
gruen 1 true
nicht rot
3.14
12.00Structs haben keine Vererbung, keine versteckten Konstruktoren oder Destruktoren: Alles ist sichtbar. Methoden sind Funktionen im Struct, self ist der erste Parameter.
Speicher und Allocators
Zig versteckt keine Heap-Allokation. Wer dynamischen Speicher braucht, bekommt einen Allocator übergeben und gibt den Speicher selbst frei (meist mit defer).
const std = @import("std");
pub fn main() !void {
const out = std.io.getStdOut().writer();
var gpa = std.heap.GeneralPurposeAllocator(.{}){}; // findet Speicherlecks
defer _ = gpa.deinit();
const alloc = gpa.allocator();
// Einzelner Wert und Slice
const zahl = try alloc.create(i32);
defer alloc.destroy(zahl);
zahl.* = 42;
const puffer = try alloc.alloc(u8, 5);
defer alloc.free(puffer);
@memset(puffer, 'x');
try out.print("{d} {s}\n", .{ zahl.*, puffer });
// Dynamische Liste
var liste = std.ArrayList(i32).init(alloc);
defer liste.deinit();
for (1..6) |i| try liste.append(@intCast(i * i));
try out.print("{any} {d}\n", .{ liste.items, liste.items.len });
_ = liste.pop();
try liste.insert(0, 99);
_ = liste.orderedRemove(1);
try out.print("{any}\n", .{liste.items});
// Text zusammenbauen
var text = std.ArrayList(u8).init(alloc);
defer text.deinit();
try text.appendSlice("Hallo");
try text.writer().print(" {s} {d}", .{ "Zig", 2025 });
try out.print("{s}\n", .{text.items});
// Formatierter String auf dem Heap
const s = try std.fmt.allocPrint(alloc, "{d}+{d}={d}", .{ 2, 3, 5 });
defer alloc.free(s);
try out.print("{s}\n", .{s});
// Hashmap
var zaehler = std.StringHashMap(u32).init(alloc);
defer zaehler.deinit();
for ([_][]const u8{ "a", "b", "a", "c", "a" }) |w| {
const eintrag = try zaehler.getOrPut(w);
if (!eintrag.found_existing) eintrag.value_ptr.* = 0;
eintrag.value_ptr.* += 1;
}
try out.print("{d} {d} {d}\n", .{ zaehler.get("a").?, zaehler.get("b").?, zaehler.count() });
}42 xxxxx
{ 1, 4, 9, 16, 25 } 5
{ 99, 4, 9, 16 }
Hallo Zig 2025
2+3=5
3 1 3| Allocator | Einsatz |
|---|---|
std.heap.page_allocator | direkt vom Betriebssystem, einfach |
GeneralPurposeAllocator | Standard mit Leck- und Doppelfreigabe-Erkennung (Debug) |
ArenaAllocator | alles auf einmal freigeben (Anfragen, Parser) |
FixedBufferAllocator | fester Stack-Puffer, kein Heap |
std.testing.allocator | in Tests: meldet Lecks |
const std = @import("std");
pub fn main() !void {
const out = std.io.getStdOut().writer();
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit(); // gibt alles auf einmal frei
const a = arena.allocator();
const eins = try a.alloc(u32, 100);
const zwei = try a.dupe(u8, "kopiert");
try out.print("{d} {s}\n", .{ eins.len, zwei });
var puffer: [64]u8 = undefined;
var fba = std.heap.FixedBufferAllocator.init(&puffer);
const kleine = try fba.allocator().alloc(u8, 16);
try out.print("{d}\n", .{kleine.len});
const zu_gross = fba.allocator().alloc(u8, 100);
try out.print("{any}\n", .{zu_gross});
}100 kopiert 16 error.OutOfMemory
Merke
structmit Feldern, Standardwerten und Methoden;enum, getaggteunion(enum)- Keine versteckten Konstruktoren/Destruktoren, keine Vererbung
- Dynamischer Speicher nur über Allocators:
alloc/free,create/destroy,defer ArrayList,StringHashMapaus der Standardbibliothek- GPA findet Lecks, Arena gibt alles auf einmal frei
Aufgabe
Lies Wörter eines Textes in eine StringHashMap und gib die Häufigkeiten aus.