I did a thing. Thing is entirely wrong? Thing is entirely ok? It ain't academic that's for sure.
Rust | Zig |
---|---|
Nominal typing (mostly*) | Nominal typing (mostly*) |
(Compares the identities (via names)) |
struct A{}; struct B{}; A != B |
Are these apples the exact same apples? |
|
Primitive types | |
bool u8, u16, u32, u64, u128, i8, i16, i32, i64, i128 f32, f64 usize, isize char, str ! // never |
bool u<bit width>, i<bit width> f16, f32, f64, f80, f128 usize, isize u8, []u8 noreturn |
Sequence types | |
Tuples | |
() (Type, ...) |
struct {} struct {Type, ...} |
Arrays | |
[Type; length] // stack [Type] // heap Vec<T> // heap resizable &[Type] // slice |
[length]Type []Type = allocator.alloc(Type, length) ArrayList(Type) []Type |
User-defined types | |
Structs | |
struct Name // unit struct Name(Type, ...) // tuple struct struct Name { prop1: Type, ... } // struct |
const Name = struct {} const Name = struct {Type, ...} const Name = struct { prop1: Type, ...} |
Enums | |
enum Name { Value1, ... } enum Name { Value1(Type, ...), ... } enum Name { Value1 { prop1: Type, ... }, ... } // match <enum> {...} is exhaustive |
const Name = enum { Value1, ... } const Name = union(enum) { Value1: Type, ... } const Name = union(enum) { Value1: Type, ... } // switch (enum/union) {...} is exhaustive |
Unions | |
union Name { prop1: Type, ... } // accesses are always unsafe { ... }! |
const Name = union { prop1: Type, ... } // compile-time union access checking! |
Function types | |
fn(Type, ...) -> Type |
*const fn (Type, ...) Type |
Pointer types | |
&Type // immutable ref / "shared ref" &mut Type // mutable ref / "unique ref" *const Type // immutable raw pointer *mut Type // mutable raw pointer |
*const Type *Type [*]const Type [*]Type |
Trait types | |
impl Trait |
// no comparison
|
Type system power | |
Turing complete (type language gymnastics) |
Turing complete (comptime) |
* both of these languages primarily use nominal type systems, but there are similar certain scenarios where structural typing can be used.