#Why cant i use undefined here
1 messages · Page 1 of 1 (latest)
std.io.GenericReader isn't a type - it's a function that returns a type
yeah but i this type does not have a name right ?
its just a big struct
from what i saw in the source code
it's not a type. you're trying to use it in a place that expects a type.
this is like writing
const foo: []const = …;
you actually meant something like
const foo: []const u8 = …;
im not sure to follow along with your last example
should I add a type after the GenericReader ?
GenericReader is a function that returns a type
it's a function, call it with the wanted arguments.
std.io.GenericReader(…, …, …)
still dont get it :////
I ended up moving all of those as global variables:
const stdin_file = std.io.getStdIn().reader();
var bw = std.io.bufferedReader(stdin_file);
const stdin = bw.reader();
so that i can use stdin in all of my functions
look at something like std.ArrayList
by itself, it is a function that returns a type
T is another type you pass in the function so that you get ArrayList(T)
that’s just how generics work in zig
The way Zig implements generic types differs from many languages. In other languages Type<T> is a type name that refers to an entire class of types that are created as part of the compilation process. In Zig, GenericReader is a function which runs at compile time which takes a type (actually multiple types) as a parameter and returns a new type after it has run.:
pub fn GenericReader(
comptime Context: type,
comptime ReadError: type,
comptime readFn: fn (context: Context, buffer: []u8) ReadError!usize,
) type { ... }
If you had filled out the parameters it would then call the function and calculate the result type at comptime, but without supplying the necessary Context, ReadError, and readFn writing GenericReader on its own just refers to this function, not the entire class of types that GenericReader can create.
Zig also relies on type erasure and duck typing with anytype to pass things like Readers and Writers around at runtime. This means you don't specify the exact type you're expecting in a lot of cases, but you use anytype and then simply call the functions you expect to be implemented by the Reader/Writer.
use this
const std = @import("std");
var stdin: std.fs.File.Reader = undefined;
test {
stdin = std.io.getStdIn().reader();
}
std.fs.File.Reader is defined here
pub const Reader = io.Reader(File, ReadError, read);
it is the return type of getstdin().reader()
it's an instantiation of GenericReader
with the correct underlying type/error/readfn
Can you expand a little more on what precisely you don't get?
how you can know what the type is going to be, for example in Mathis code he somehow knew that the return type was going to be std.fs.File.Reader , because when I jump to definition the return type of reader() function i get jumped to the return struct of the GenericReader
Because getStdIn() returns a std.fs.File
And there's a bit of a convention that types that have .reader() member procs define a Reader decl inside them, which matches the return type of that proc
Just like here.
"A io.Reader which stores a state of type std.fs.File, returns an error of type std.fs.File.ReadError, and calls the std.fs.File.read function to read data."