Adrian Savage
Adrian Savage

Reputation: 223

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

Upvotes: 7

Views: 3929

Answers (2)

sigod
sigod

Reputation: 6486

io.Writer is a generic data structure. I.e. it's a function that returns a type. You cannot use it as a function argument, but you can:

anytype is required for functions that must accept arbitrary writers. Otherwise, it might be nicer to use an alias or a "proxy" type.

Upvotes: 7

ad absurdum
ad absurdum

Reputation: 21363

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!

Upvotes: 5

Related Questions