Coming from javascript and typescript, you might see Zig's var
and const
and have a concept of what that means. var
is short for variable, const
is short for constant. Variable vs Constant: easy-peasy. Wait not so fast! This post will help you test out those concepts, and get comfy with Zig's var
and const
.
Allows changing values
zig var
|
zig const
|
js var
|
js let
|
js const
|
---|---|---|---|---|
✔️ | ❌ | ✔️ | ✔️ | 😬 |
Let's step through that table with some examples:
zig var
var x: u8 = 0;
x += 255;
std.log.info("{}", .{ x });
// info: 255
Yep, we can change var
's value.
zig const
const x: u8 = 0;
x += 255;
// error: cannot assign to constant
No surprises here.
js var
and let
var x = 0;
x += 255;
console.log(x);
// 255
let y = 0;
y += 255;
console.log(y);
// 255
Both allow changing of value. Hence "variable". All is right with the world.
js const
const x = 0;
x += 255;
// TypeError: Assignment to constant variable.
Javascript prevents assignment to const. What about changing a value of a const (like, of an object?)
const foo = { id: 42, color: 'blue', health: 8 };
foo.health += 100;
console.log(foo);
// { id: 42, color: 'blue', health: 108 }
Javascript does not prevent you changing the value of a const ! Unless you use Object.freeze() which is let's face it: pretty obscure, in practice.
Javascript's const isn't really weak, it's just that every non-primitive variable is essentially a pointer (DoctorQuantum)
Here we could go down the rabbit hole of javascript memory model vs zig memory model, but this is just a #learning post (and I'm not up to speed on all that). Let's just keep it "in practice".
Try the same foo
example in zig:
const std = @import("std");
const FooMonster = struct {
id: usize,
color: []const u8,
health: u8,
};
pub fn main() void {
const foo = FooMonster{ .id = 42, .color = "blue", .health = 8 };
foo.health += 100;
// error: cannot assign to constant
std.log.info("{}", .{ foo });
}
Change foo
to be var
, and then you can assign a new health value.
Scope
Zig variables may be container level, static local, thread local, or just local. Blocks are used to scope variable declarations.
zig var
|
zig const
|
js var
|
js let
|
js const
|
---|---|---|---|---|
block | block | function 😩 | block | block |
There is no equivalent of Js var
scoping in Zig. Js let
was invented because function scoping was, well, not the best in practice.
Redeclaring
Js let
does not allow redeclaring. Shadowing and hence, re-declaration, are not a thing in Zig.
Further Study
- Zig has some different rules than JavaScript about initialization of variables.
- Pointers have their own "const-ness".
- Zig adds a new concept
comptime
! The value of variable must be known or computable at compile time.
Learn more in the Language Reference.
Parting thoughts
It is generally preferable to use const rather than var when declaring a variable. This causes less work for both humans and computers to do when reading code, and creates more optimization opportunities. (Zig language reference)
Oldest comments (2)
Thanks for the writeup!
Yep, that's probably worthy of its own blog post :^)
Author here: in TypeScript we got "const assertions" typescriptlang.org/docs/handbook/r...
Which are kind of related to the examples above.