определение структуры с помощью var вместо const в языке zig

Я сейчас учусь zigязык. Я видел определения структур сconst ключевое слово вроде

const X = struct {
    n: i32,
};

Насколько я понимаю, const является своего рода дополнением к var, последний допускает изменения, а первый - нет. Но что означало бы определение структуры с помощьюvar?

var Y = struct {
    n: i32,
};

Это законно? Я компилирую, так что да, это так. Но в чем смысл и польза от этого?

1 ответ

Решение

Это компилируется, потому что zig вычисляется лениво. Потому какY не используется, компилятор не проверяет.

Когда вы ссылаетесь на него, компилятор выдает ошибку:

Попробуйте этот код

var Y = struct {
    n: i32,
};

comptime {
    @compileLog(Y);
}
error: variable of type 'type' must be constant
    var Y = struct {
    ^

varобъявлять переменные. Когда вы используетеvar в глобальной области видимости, которая создает глобальную переменную.

В твоем случае,

var Y = struct {
    n: i32,
};

Объявляет Yкак переменная входящего типа. В этом случае,Y это переменная типа type.

В zig есть типы только для времени, то есть в случае type. Значение, тип которого является типом только для времени, может находиться внутри компилятора, вы не можете создать значение во время выполнения1. Итак, компилятор всегда должен знать значение, известное во время компиляции.

Потому, что Yглобальная переменная. Вы можете изменить его во время выполнения. Это причина ошибки. ЗначениеY не может быть сгенерирован / сохранен двоичным файлом.


Если только живет в компиляторе, работает

Попробуйте этот код

comptime {
    var Y = struct {
        n: i32,
    };

    Y = struct {
        count: u32,
    };

    const concrete = Y { .count = 10 };

    @compileLog(concrete.count);
}
| 10 

Приложение

1 Например, рассмотрим

Попробуйте этот код

const std = @import("std");

fn compilerKnown(arg: []const u8) type {
   return u64;
}

pub fn main() !void {
    var runtimeValue = "hello world";

    std.debug.print("{}\n", .{ compilerKnown(runtimeValue) });
}
error: unable to evaluate constant expression
    std.debug.print("{}\n", .{ compilerKnown(runtimeValue) });
                                             ^

Это ошибка, потому что zig пытается скомпилировать функцию compilerKnown в двоичный, но тип typeработает только в режиме comptime, поэтому не может создать двоичный файл. В частности, не может сгенерировать машинный код дляreturn u64.

Другие вопросы по тегам