почему пользовательские типы в 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 перед именем, в противном случае он считается недействительным токеном.

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