Die eingebauten Typen
Zero gibt dir einen kleinen, regulären Satz primitiver Typen. Nichts Exotisches, nichts Überraschendes – einfach die, die jede Systems-Sprache braucht, konsistent benannt.
| Familie | Typen | Hinweise |
|---|---|---|
| Vorzeichenbehaftete Integer | i8, i16, i32, i64 | Zweierkomplement. |
| Vorzeichenlose Integer | u8, u16, u32, u64 | Nur 0 und positiv. |
| Zeigergroß | usize, isize | Breite entspricht dem Plattform-Pointer. |
| Floats | f32, f64 | IEEE-754. |
| Boolean | bool | true oder false. |
| Zeichen | char | Ein einzelner Unicode-Skalar. |
| String | String | UTF-8-String. |
| Leer | Void | „Kein nützlicher Wert." |
Das ist die vollständige Liste der Primitives, die du im Alltag anfasst. Zusammengesetzte Typen – Shapes, Enums, Choices – werden aus diesen gebaut.
Integer
Die Integer-Typen folgen einem einheitlichen Namensmuster: i für signed, u für unsigned, gefolgt von der Bit-Breite. Also ist i32 ein 32-Bit-signed-Integer; u8 ein unsigned Byte; i64 ein 64-Bit-signed-Integer.
let small_signed: i8 = -120
let byte: u8 = 250
let id: i32 = 1
let big: i64 = 9_000_000_000
let index: usize = 0
Der Default für ein Literal ohne Suffix ist i32, sofern der Kontext nichts anderes erzwingt:
let answer = 42 // i32
Wenn du eine bestimmte Breite brauchst, hänge ein Suffix ans Literal oder annotiere das Binding:
let byte = 250_u8 // typisiertes Literal
let byte: u8 = 250 // typisiertes Binding
Beide Formen ergeben denselben Wert. Die Literal-Suffix-Form ist praktisch, wenn du ein Literal direkt an eine Funktion übergibst oder eine Struktur aufbaust:
let pair: BytePair = Pair { left: 1_u8, right: 2_u8 }
Welche Breite wählen?
Eine kurze Faustregel:
i32für die meiste signed-Mathematik. Breit genug für fast alles, was du zählst, und auf jeder Plattform schnell.u8für Arbeit auf Byte-Ebene. Bytes aus einer Datei, Bytes in einem Puffer, Bytes übers Netzwerk.u32/u64für nicht-negative Zähler, wenn der Wertebereich zählt. Datei-Offsets über 2 GB, große Zähler.usizefür Größen und Indizes. Zeigergroß – passt zu dem, was die Plattform für Speicheradressierung benutzt.i64für Zeit-seit-Epoche und Ähnliches. Groß genug für Nanosekunden über Hunderte von Jahren.
Den kleinstmöglichen passenden Typ zu wählen ist gute Praxis; einen zu kleinen Typ zu wählen und einen Überlauf zu produzieren ist ein deutlich größeres Problem als einen, der ein Bit zu breit ist.
Booleans
let ok = true
let done: bool = false
bool hat genau zwei Werte: true und false. Es sind Literale, keine Konstanten, die du irgendwoher importierst. Die Bedingung in if oder while ist ein bool – es gibt keine implizite Wahrheits-Interpretation für Integer oder Strings.
if ok {
check world.out.write("yes\n")
} else {
check world.out.write("no\n")
}
If/Else behandelt Konditionale im Detail.
Floats
f32 und f64 sind 32-Bit- bzw. 64-Bit-IEEE-754-Fließkommazahlen. Nutze sie, wenn du Bruchwerte brauchst – Messwerte, Verhältnisse, Geometrie. Für exakte Arithmetik bei Geld nimm lieber Integer in der kleinsten Einheit (Cent, Satoshi) statt Floats.
let ratio: f32 = 0.5
let pi: f64 = 3.141592653589793
f64 ist der Default für Float-Literale ohne Suffix.
Zeichen und Strings
Ein char hält einen einzelnen Unicode-Skalarwert:
let initial: char = 'Z'
Ein String ist eine Zeichensequenz, von der Standardbibliothek typischerweise als UTF-8 kodiert. String-Literale verwenden doppelte Anführungszeichen:
let message: String = "hello from zero\n"
Die erwarteten Escape-Sequenzen funktionieren – \n für Zeilenumbruch, \t für Tab, \\ für einen literalen Backslash, \" für ein literales doppeltes Anführungszeichen.
let multi_line = "line one\nline two\n"
Die Standardbibliothek bietet byte-orientierte Sichten auf einen String für Low-Level-Arbeit. Die Form std.mem.span("zero") liefert ein Span<u8> über die Bytes – nützlich beim Parsen, Hashen oder bytewiesen Vergleichen.
Void
Void ist Zeros „kein nützlicher Rückgabewert"-Typ. Funktionen, die es nur wegen ihrer Seiteneffekte gibt, verwenden ihn:
pub fun main(world: World) -> Void raises {
check world.out.write("hello\n")
}
main schreibt etwas und kehrt zurück. Es gibt keinen Wert zurückzugeben, also ist der Typ Void. Du wirst Void bei den meisten Funktionen sehen, die World anfassen – sie werden wegen ihres Effekts, nicht wegen ihres Ergebnisses gewählt.
Unterstriche in Zahl-Literalen
Lange Zahl-Literale dürfen Unterstriche als visuelle Trenner verwenden. Der Compiler ignoriert sie, sie sind also ein reines Lesbarkeits-Feature:
let big = 9_000_000_000_i64
let bytes = 1_048_576_u32 // 1 MiB
Setze sie überall, wo es schwer wird, die Ziffern zu zählen.
Typisierte Literal-Suffixe – Spickzettel
| Suffix | Typ | Beispiel |
|---|---|---|
_i8 / _i16 / _i32 / _i64 | Signed Integer | 127_i8 |
_u8 / _u16 / _u32 / _u64 | Unsigned Integer | 255_u8 |
_usize / _isize | Zeigergroß | 0_usize |
_f32 / _f64 | Float | 0.5_f32 |
Greif zu diesen, wenn du einen Wert baust und der Kontext den Typ nicht festnagelt.
Als Nächstes: Funktionen
Primitive sind nutzlos, ohne dass du etwas mit ihnen machst. Das nächste Dokument behandelt Funktionen in Zero – wie du sie deklarierst, Werte zurückgibst und sie zu echten Programmen zusammenstellst.
Häufig gestellte Fragen
Welche primitiven Typen hat Zero?
Zero kommt mit den Größen-Integern i8, i16, i32, i64; den vorzeichenlosen u8, u16, u32, u64; den zeigergroßen usize und isize; den Floats f32 und f64; bool; char; String; und Void für Funktionen, die keinen nützlichen Wert zurückgeben.
Was ist der Default-Integer-Typ in Zero?
Ein Integer-Literal ohne Suffix wie 42 ist standardmäßig i32, sofern der Kontext nicht etwas anderes erzwingt. Für eine bestimmte Breite schreibst du das Literal mit Suffix wie 42_u8 oder 42_i64, oder annotierst den Typ des Bindings explizit mit let count: u8 = 42.
Hat Zero einen eigenen String-Typ?
Ja. String-Literale wie "hello" haben einen eingebauten String-Typ, den die Standardbibliothek als Byte-Sequenz behandelt (typischerweise UTF-8). Für Arbeit auf Byte-Ebene bietet die Standardbibliothek Spans und Byte-Utilities; für Operationen auf Zeichenebene gibt es char für einzelne Skalarwerte.
Was bedeutet Void in Zero?
Void ist der Rückgabetyp einer Funktion, die keinen nützlichen Wert produziert – sie existiert nur wegen ihrer Seiteneffekte. Die konventionelle Signatur pub fun main(world: World) -> Void raises verwendet Void, weil main da ist, um I/O zu machen und zu beenden, nicht um einen Wert zu liefern.
Was ist der Unterschied zwischen i32 und u32 in Zero?
i32 ist ein vorzeichenbehafteter 32-Bit-Integer mit Wertebereich von −2.147.483.648 bis 2.147.483.647. u32 ist vorzeichenlos und hat den Bereich 0 bis 4.294.967.295. Nimm vorzeichenbehaftete Typen, wenn negative Werte einen Sinn ergeben, und vorzeichenlose, wenn negative Werte ein Bug wären – für Zähler, Indizes, Größen und so weiter.