Search code examples
function-callzig

What is the better way to pass a hashmap as Argument in zig?


Currently learning zig, but I am stuck with a problem about passing a hashmap into a fucntion. Although I have a working solution, I am not satisfied with using the anytype keyword, and I am seeking for a better practice.

Originally, I wrote my code like shown:

pub fn experimenting_hashmap(bw: anytype, stdout: anytype) !void {
    const page = std.heap.page_allocator;
    var arena = std.heap.ArenaAllocator.init(page);
    defer arena.deinit();

    var map = std.AutoHashMap(i32, i32).init(arena.allocator());
    defer map.deinit();

    try map.put(1, 2);
    try map.put(2, 4);
    try map.put(4, 7);
    try map.put(7, 3);
    try map.put(3, 5);
    try map.put(5, 1);

    try stdout.print("\nPrinting a hashmap: ", .{});
    try get_key(stdout, map, 1, 10);
    try bw.flush();
}

// the problem of the code is this function definition
pub fn get_key(stdout: anytype, map: std.AutoHashMap, cur_index: i32, no_iter: i32) !void {
    try stdout.print("{d} -> ", .{cur_index});

    if (no_iter == 0) {
        try stdout.print("{d}\n", .{map.get(cur_index).?});
        return;
    } else {
        try get_key(stdout, map, map.get(cur_index).?, no_iter - 1);
    }
}

This refuses to compile because of an error for the hashmap input parameter type in the get_key() function:

error: expected type 'type', found 'fn (comptime type, comptime type) type'
pub fn get_key(stdout: anytype, map: std.AutoHashMap, cur_index: i32, no_iter: i32) !void {
                                ^~~

I was seeking a solution from the zig guide and even the test cases from the hash_map.zig, and they don't seem to have any hints or ideas for passing a hashmap as an input parameter. The closest solution I could found was to use anytype for the hashmap, which the code works if I write like the following:

pub fn get_key(stdout: anytype, map: anytype, cur_index: i32, no_iter: i32)

However, I am not satisfied with the solution because it seems a bit unclear if this is a function used for a library which you have to guess the input type if there is no documentation.

Is there a better way to pass a hashmap as an input parameter, other than using anytype?


Solution

  • I have actually found the answer during waiting for the post being made to the public, but I didn't remove it because I might find it useful for some, so here is the solution:

    Instead of using map: std.AutoHashMap, I need to declare the type for the AutoHashMap, thus:

    pub fn get_key(stdout: anytype, map: std.AutoHashMap(i32, i32), cur_index: i32, no_iter: i32)...
    

    The Error message actually reflects such suggestion because the function is expecting a hashmap type with no type definitions (data type for both key and value), but I what I have feed into the function is a hashmap with two data type definition (i32, i32), causing a type mismatch.