почему пользовательские типы в zig должны быть константными?
Если мне нужно объявить структуру в Zig, я должен добавить к ней префикс
const
const Arith = struct {
x: i32,
y: i32,
fn add(self: *Arith) i32 {
return self.x + self.y;
}
};
test "struct test" {
var testArith = Arith{
.x = 9,
.y = 9,
};
expect(testArith.add() == 18);
}
Но его можно инициализировать обоими способами как
var
и
const
Итак, почему для объявления типа требуется ключевое слово constant, когда важно только то, является ли экземпляр структуры
const
или нет?
2 ответа
Нужно быть
const
поскольку порядок оценки в корневой области не определен, а переменные типа
type
может жить только в компиляторе (не имеет представления в памяти, компилятор не может создать его двоичное представление). Но вы можете использовать
var
внутри других областей:
comptime {
var T = struct { value: u64 };
const x: T = .{ .value = 3 };
T = struct { ok: bool };
const y: T = .{ .ok = true };
@compileLog(x.value); // <- 3
@compileLog(y.ok); // <- true
}
В остальном ответ я подробно объясню.
Const
const Arith = struct {...};
Создает постоянную переменную предполагаемого типа. В этом случае переменная
Arith
имеет тип
type
:
const Arith = struct {...};
comptime {
@compileLog(@TypeOf(Arith)); // <- type
}
Это то же самое, что объявить переменную как:
const Arith: type = struct {...};
Вар
Вы также можете создать переменную с помощью
var
Примеры:
comptime {
var Arith = struct {...};
}
comptime {
var Arith: type = struct {...};
}
fn main() !void {
comptime var Arith = struct {...};
}
fn main() !void {
var Arith: type = struct {...};
}
fn main() !void {
comptime var Arith: type = struct {...};
}
Поскольку это переменная, вы можете изменить ее:
comptime {
var T = u64;
T = bool;
@compileLog(T); // <-- bool
}
Типы Comptime
Есть типы, которые могут жить только в компиляторе, например:
type
или структуры, которые имеют поле типа
anytype
или другой тип comptime.
На случай, если
type
, это заставит компилятор интерпретировать
var x: type
в виде
comptime var x: type
.
Затем рассмотрите следующий код:
var T = struct { value: u64 }; // <- Compiler error
comptime {
const x: T = .{ .value = 3 };
}
error: variable of type 'type' must be constant
поскольку порядок оценки в корневой области не определен, компилятор вынуждает создать глобальную переменную внутри двоичного файла, но тип
type
не имеет представления в памяти. Итак, компилятор выдает ошибку.
Поскольку
Arith
относится к типу
type
он должен быть объявлен константой, потому что компилятор этого ожидает. Это можно проверить, изменив объявление типа на this и запустив программу
var Arith = struct {
x: i32,
y: i32,
fn add(self: *Arith) i32 {
return self.x + self.y;
}
};
что приведет к ошибке
error: variable of type 'type' must be constant
Также в Zig нам понадобится либо
const
или
var
перед именем, в противном случае он считается недействительным токеном.