Search code examples
zig

How do I pass a stream or writer parameter to a function in Zig?


I'm trying to pass the output stream to a function but can't get it right. This sample code shows a couple of the things I've tried

// Attempts to pass stream or writer to a function
const std = @import("std");
pub fn main() !void {

  // #1
  try print1(std.io.getStdOut(), "Hello, ");

  // #2
  try print2(std.io.getStdOut().writer(), "world!");

}

// error: 'File' is not marked 'pub'
pub fn print1(file: std.io.File, str: []const u8) !void
{
  try file.writer().print("{s}", .{str});
}

// error: expected type 'type', found 'fn(comptime type, comptime type, comptime anytype) type'
fn print2(writer: std.io.Writer, str: []const u8) !void
{
  try writer.print("{s}", .{str});
}

I'm using Zig 0.10.0


Solution

  • The call to std.io.getStdOut() returns a File, but the File type is in the std.fs namespace. Calling std.io.getStdOut().writer() returns a Writer from the std.fs.File namespace. You could also declare the writer parameter with the anytype keyword to get type inference at the time of the function call.

    Here is a modified version of OP posted code:

    const std = @import("std");
    
    pub fn main() !void {
        const stdout = std.io.getStdOut();
        const writer = stdout.writer();
    
        // #1
        // Pass `stdout` to a function:
        try print1(stdout, "Hello, ");
    
        // #2
        // Pass a `Writer` to a function:
        try print2(writer, "world!\n");
    
        // #3
        // Pass a `Writer` to a function:
        try print3(writer, "Hello, again!\n");
    }
    
    fn print1(file: std.fs.File, str: []const u8) !void {
        try file.writer().print("{s}", .{str});
    }
    
    // Explicit type annotation for `writer`:
    fn print2(writer: std.fs.File.Writer, str: []const u8) !void {
        try writer.print("{s}", .{str});
    }
    
    // The type of `writer` is inferred when the function is called:
    fn print3(writer: anytype, str: []const u8) !void {
        try writer.print("{s}", .{str});
    }
    

    And a sample run:

    $ zig run print_stream.zig 
    Hello, world!
    Hello, again!