I decided to learn how const works.
I hope it will be useful.
The last test struct with reference types really caused me a lot of confusion on a real project.
Part 1:
/// What I Should Known About constants in Zig
///
/// Part 1, scalars.
///
/// I decided to write this program because, coming from High Level programming
/// Languages like Python and Go, I was very confused with the actual behavior.
///
/// Another purpose is to improve how const works in the Zig Language Reference.
///
/// I also added documents from Wikipedia and Mozilla, and some questions.
///
///
/// Notes from https://en.wikipedia.org/wiki/Constant_(computer_programming)
///
/// There are various specific realizations of the general notion of a constant,
/// with subtle distinctions that are often overlooked.
///
/// The most significant are: compile-time (statically valued) constants,
/// run-time (dynamically valued) constants, immutable objects, and constant
/// types (const).
///
///
/// Question 1:
/// const applies to all of the bytes that the identifier immediately addresses.
/// What is the meaning, for scalar values?
///
/// Question 2:
/// Is Zig const the same as the one in C, C++ and JavaScript?
///
/// Question 3:
/// However, unlike in other languages, in the C family of languages the const
/// is part of the type, not part of the object.
/// Does this apply to Zig?
///
///
/// Note from Javascript
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const
///
/// The const declaration creates an immutable reference to a value.
/// It does not mean the value it holds is immutable — just that the variable
/// identifier cannot be reassigned.
///
/// For instance, in the case where the content is an object, this means the
/// object's contents (e.g., its properties) can be altered.
///
/// You should understand const declarations as "create a variable whose identity
/// remains constant", not "whose value remains constant" — or, "create
/// immutable bindings", not "immutable values".
const std = @import("std");
const Allocator = std.mem.Allocator;
const testing = std.testing;
fn runTimeConstant(value: i32) void {
// run-time constant (dynamically valued)
const b: i32 = value * 3;
b = 3;
// const.zig:36:9: error: cannot assign to constant
// b = 3;
// ^
}
test "compile-time constant" {
// compile-time constant (statically valued)
// stored in the global constant data section
const a = 100;
a = 10;
// const.zig:22:9: error: cannot assign to constant
// a = 10;
// ^
//_ = a;
}
test "run-time constant" {
runTimeConstant(100);
}
test "immutable object" {
// immutable objects
// object that has a primitive type and scalar values?
//
// Actually, create immutable bindings, not immutable values.
const b: i32 = 7;
b = 5;
// const.zig:28:5: error: cannot assign to constant
// b = 5;
// ^
}
test "xxx" {
// Adapted from https://en.wikipedia.org/wiki/Const_(computer_programming)#D
var c: [5]i32 = .{ 1, 2, 3, 4, 5 }; // d is mutable.
const d: [5]i32 = c; // x is a const view of mutable data.
c[1] = 10;
try std.testing.expectEqual(c[1], 10);
d[1] = 100;
// const.zig:27:8: error: cannot assign to constant
// d[1] = 100;
// ~~~^~~
_ = &c;
_ = &d;
}
test "array" {
// Example from JavaScript
// Not available in the Zig Language Reference.
// Please, add it.
//
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const
const array: [5]i32 = .{ 1, 2, 3, 4, 5 };
array[1] = 5;
// const.zig:48:10: error: cannot assign to constant
// array[1] = 5;
// ~~~~~^~~
}
test "struct with primitive types" {
const example = struct {
x: i32,
};
// Fail because the x field has a primitive type/immutable?
const a = example{ .x = 7 };
a.x = 5;
// const.zig:93:6: error: cannot assign to constant
// a.x = 5;
// ~^~
}
Part 2
/// What I Should Known About constants in Zig
///
/// Part 2, references.
const std = @import("std");
const testing = std.testing;
test "struct with reference types" {
const Step = struct {
power: u32,
};
const Workout = struct {
steps: []Step,
};
const step = Step{ .power = 200 };
// Convert an array to a slice
var array = [_]Step{step};
const slice = array[0..array.len];
const wko = Workout{ .steps = slice };
// Mutate the data is allowed.
wko.steps[0].power = 250;
try testing.expectEqual(wko.steps[0].power, 250);
// Mutate the data is not allowed.
// Not sure why.
//
// Both `wko` indentifier and `power` identifiers access the bytes that the
// identifiers immediately addresses?
const power = wko.steps[0].power;
power = 300;
// const-reference.zig:60:5: error: cannot assign to constant
// power = 300;
// ^~~~~
try testing.expectEqual(power, 300);
}
Let me known if same definitions are incorrect and if
some one can add good examples in the Zig Reference.
Thanks