Reputation: 223
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
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
.fs.File.Writer
.fs.File
, on which you'll call writer()
.io.Writer(fs.File, fs.File.WriteError, fs.File.write)
.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
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