Both seem to compile just fine and (IMO, of course) the second one makes the generic nature of the type more clear. I’m wondering if there is a reason for it that’s to do with something deeper in the language somewhere.
var foo = T{ .a = 1, .b = 2 };
// or
var foo = @as(T, .{ .a = 1, .b = 2 });
is semantically equivalent to
const temp: T = .{};
temp.a = 1;
temp.b = 2;
var foo = temp;
In other words, the former operates directly on the result variable while the latter creates a temporary variable, initializes it completely and then copies the result over to the result variable.
When initializing a completely new variable there will be no difference between the two, but when reassigning based on the previous value of the variable it does make a difference:
var foo: T = .{ .a = 1, .b = 2 };
foo = .{ .a = foo.b, .b = foo.a }; // .{}
assert(foo.a == 2);
assert(foo.b == 2);
var bar: T = .{ .a = 1, .b = 2 };
bar = T{ .a = bar.b, .b = bar.a }; // T{}
assert(bar.a == 2);
assert(bar.b == 1);
As a side note, because T{} and @as(T, .{}) are equivalent, it is possible that the T{} syntax will be removed in the future.
@castholm is completely correct – the only difference is the application of RLS. For most purposes, these syntax forms are equivalent.
Broadly speaking, .{ ... } is the preferred syntax. As mentioned above, it is possible that T{ ... } will be removed in the future. The few places where official documentation uses this syntax are probably just outdated, and thus don’t conform to today’s conventions.