Exporting Generic Implementations from different files

I am very new to zig and and as a learning exercise I wrote a generic implementation of a singlarly linked list it looks like this:

pub fn SLinkedList (comptime T: type) type {

    return struct {
        const Node = struct {
            data: T, next: ?*Node,
        };

        const Self = @This();

        head: ?*Node = null,
        tail: ?*Node = null,
        len: usize = 0,
        allocator: std.mem.Allocator,

        pub fn init (allocator: Allocator) SLinkedList(T) {

            return .{
                .head = null,
                .tail = null,
                .len=0,
                .allocator = allocator,
            };
        }
==== truncated ===

it works well on it’s own and has been thuroughly tested.

I have managed to get the include in a test file which is:

const std = @import("std");
const SLinkedList = @import("SLinkedList.zig");

var Arena = std.heap.ArenaAllocator.init(std.heap.smp_allocator);
const gpa = Arena.allocator();

pub fn main () !void {

    const list_type = SLinkedList[usize];
    var list = list_type.init(gpa);
    for (0..100) |i| {
        try list.add(i);
    }

}

When I try to do a zig run my compiler output is the following:

❯ zig run src/main.zig
src/main.zig:9:35: error: expected type 'usize', found 'type'
    const list_type = SLinkedList[usize];
                                  ^~~~~

Clearly there’s a type mismatch, what am I doing wrong?

Welcome to Ziggit @Delvaris!

Within Zig, files are structs, @import("SLinkedList.zig"); imports the file-scope struct that represents that file, which has the generic function SLinkedList as a declaration.

So you need to access it explicitly:

const SLinkedList = @import("SLinkedList.zig").SLinkedList;

This can’t be avoided with generic types, because there is no way to make a function into the result of the @import.


Brackets following an identifier are for subscript access aka array/slice access.
You need to use parentheses to call functions.

const List = SLinkedList(usize);

Types are captialized by convention, which makes the _type unnecessary.

Array access expects an index which is an instance of type usize, while you are trying to call a generic function with the type usize (not an instance).

2 Likes

thank you for your answer! I knew something just wasn’t clicking and it was probably simple.

1 Like