3 ms·
"Dot" in zig is a placeholder for types that can be unambigously inferred from the surrounding expression. So ".unknown" is a standin for "SomeEnum.unknown" or
by thrwyexecbrain 3mo ago
"Dot" in zig is a placeholder for types that can be unambigously inferred from the surrounding expression.
So ".unknown" is a standin for "SomeEnum.unknown" or "SomeStruct.unknown", depending on what .format is.
- coxmi 3mo agoYeah, after looking it up, it looks like it is basically only used as either field access or an 'infer operator', is that right? I thought it was used in four completely separate ways: · normal struct field access · anonymous struct definition · field definition within structs (for reasons to do with the parser) · an extra 'infer operator' for syntactic sugar But there's no support for anonymous structs/fields, and all structs and fields require a type somewhere for it to be inferred. Which is why this is invalid zig: const test = .{ .x = 0, .y = 1 }; (It would need the type to be specified in the called function definition, or inline when assigning) Correct me if I'm wrong here! (And thank you)
- tremon 3mo agoI don't think that "infer operator" is a special case of field access, to me it feels like regular known-type elision similar to how C# and C++ use the var keyword if the data type can be inferred from the rhs expression: const Enum = enum {one, two, five}; const t: Enum = .one; // Enum.one, but the type was inferred from lhs std.debug.print("{t}\n", .{t}); Defining an anonymous struct is valid in zig; your example is only invalid because "test" is a reserved keyword. But you are correct that it reifies into a concrete type, and after initialization it doesn't coerce into other types because zig doesn't do structural typing: const anonymous = .{ .x = 0, .y = 1 }; std.debug.print("{}\n", .{@TypeOf(anonymous)}); // will output something like test_0__struct_45138 const Point = struct { x: i32, y: i32 }; const p1 = Point{ .x = 0, .y = 1 }; // valid, explicit struct literal const p2: Point = .{ .x = 0, .y = 1 }; // valid, anonymous struct will coerce to Point //const pt: Point = anonymous; // error: expected type 'test_0.Point', found 'test_0__struct_45138' And then there's fieldless anonymous structs aka tuples. I'm including them because they were used in the print statements above: const tuple = .{ 0, "1", true }; std.debug.print("{}\n", .{@TypeOf(tuple)}); // struct { comptime comptime_int = 0, comptime *const [1:0]u8 = "1", comptime bool = true }
- coxmi 3mo agoThanks for the detailed answer :) All this does for me is raise the question of why they chose to use the `.` for so many different uses. I'd be fine if it was just to infer the type, but it seems very overloaded.