Выделение общей структуры в Zig lang

Можно ли создать выделение для struct, содержащее тип в качестве атрибута?

Например

Пример структуры

const Content = struct {
    content: type,
    name: []const u8,
};

Затем я хотел бы выделить память, например, 2 * Content

Я знаю, что мог бы использовать

const list: [2]CustomElement = .{ Content{ .content = Type, .name = "test" }, Content{ .content = Type, .name = "test" } };

Но как добиться того же, используя allocators ?

Это не работает.

  comptime {
        var list = std.ArrayList(Content).init(test_allocator);
        try list.append(Content{ .content = MyType , .name = "test" });
    }

я получаю сообщение об ошибке

error: parameter of type '*std.array_list.ArrayListAligned(Content,null)' must be declared comptime

Кратко

Можно ли создать функциональность для чего-то вроде Box в Rust?


person Tonis    schedule 11.10.2020    source источник


Ответы (1)


Насколько я понимаю, я не думаю, что распределители, доступные в настоящее время в языке (0.6.0 на момент написания), которые обычно требуют параметра типа «comptime», в настоящее время позволяют это.

Из текущей документации, относящейся к comptime, относительно типа type:

В Zig типы — граждане первого класса. Их можно присваивать переменным, передавать в качестве параметров функциям и возвращать из функций. Однако их можно использовать только в выражениях, которые известны во время компиляции, поэтому параметр T в приведенном выше фрагменте должен быть помечен comptime.

Это похоже на то, что должно быть возможно, поскольку я думаю, что type должен иметь размер, и вы, вероятно, могли бы выделить структуру, которая могла бы его удерживать.

Похоже, что выделение comptime — это вариант использования, который может поддерживаться в следующих версиях: https://github.com/ziglang/zig/issues/1291, но я не уверен, как это будет взаимодействовать с type.

Я новичок в Zig, поэтому, надеюсь, кто-то даст более полный ответ = D

Изменить: я уверен, что это не тот вопрос, который вы задаете, но если, как в приведенном выше примере, вы сохраняете в списке только объекты одного типа, я думаю, вы может что-то сделать с дженериками?

e.g.

const std = @import("std");

pub fn main() anyerror!void {
    const cw = ContentWrapper(MyType);

    var list = std.ArrayList(cw.Content).init(std.heap.page_allocator);
    try list.append(cw.Content{ .content = MyType{ .id = 1, .property = 30 }, .name = "First" });
    try list.append(cw.Content{ .content = MyType{ .id = 2, .property = 10 }, .name = "Second" });
}

const MyType = struct {
    id: u8, property: f32
};

fn ContentWrapper(comptime T: type) type {
    return struct {
        pub const Content = struct {
            content: T, name: []const u8
        };
    };
}
person Chris    schedule 16.10.2020
comment
Эй, спасибо за ответ, в основном я хотел знать, могу ли я сделать в Zig что-то вроде Box в Rust. Но я думаю, что вы правы, я должен просто переосмыслить свой способ делать что-то в Zig, возможно, есть лучший способ сделать это :) - person Tonis; 19.10.2020
comment
Интересно, я думаю, вы могли бы обернуть некоторые функции распределения памяти в какой-то общий боксер (используя распределитель), хотя, вероятно, это было бы не так аккуратно. Похоже, есть несколько открытых вопросов, связанных с управлением памятью на будущее, надеюсь, кто-нибудь придет и даст более полезный ответ =D - person Chris; 19.10.2020