-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal: default struct field initialization values #485
Comments
Yes please.
(There may be better ways to do this, but I couldn't find any) |
You can simply assign the type to a new identifier in these cases.
|
Want this. |
I never elaborated on those use cases - I admittedly didn't give this much thought after posting it. It fills some of the roles optional function arguments intended to, but has a few caveats. Default field initialization values could be abused to make structs carry implicit allocators, or even hide conditional declaration of fields. A lesser version of this feature that would prevent the above abuse but is still somewhat useful is to only allow specific values to be set (like zeroes), or only allow fields to be omitted from initialization if their default is undefined
Zig used to have the concept of
even The status quo solution is to instantiate structs with a function, which is simple enough, refactor-friendly and probably good practice anyway... I'm actually pretty satisfied without this feature. EDIT: Clarified phrasing |
Isn't this a slippery slope to more implicit function calls. I agree init can be tedious, but it is definitely simpler. |
Yeah, either the instantiation or the function call would end up more implicit. I'd expect less implicit behavior when instantiating a struct because it seems like a more primitive operation than calling a function. A function call is basically control flow and you explicitly know something is going on behind the scenes. |
Would be very handy for |
There should definitely be a limit on what the default values should be, and the most obvious restriction is the same one for global var/const initializers: the value has to be known at comptime. So you can't get clients to call functions by omitting a field or anything. |
This can be used for optional arguments: const OpenFileOptions = struct{
flags: i32 = posix.O_READ | posix.O_EXCL,
mode: i32 = 0o744,
};
fn openFile(path: []const u8, options: OpenFileOptions) File {
...
}
test "asdf" {
_ = openFile("asdf", OpenFileOptions{});
_ = openFile("asdf", OpenFileOptions{.flags = 0});
_ = openFile("asdf", OpenFileOptions{.flags = 0, .mode = 0});
} The name of the struct is awkward, but that's mitigated with this proposal #208 (comment) where you could do |
An idea from @MasonRemaley is that you should have to opt in to the optional values when constructing a struct. It might look like this: const OpenFileOptions = struct{
flags: i32 = posix.O_READ | posix.O_EXCL,
mode: i32 = 0o744,
};
test "asdf" {
_ = openFile("asdf", OpenFileOptions{}); // ERROR
_ = openFile("asdf", OpenFileOptions{...}); // OK
_ = openFile("asdf", OpenFileOptions{.flags = 0}); // ERROR
_ = openFile("asdf", OpenFileOptions{.flags = 0, ...}); // OK
_ = openFile("asdf", OpenFileOptions{.flags = 0, .mode = 0}); // OK
_ = openFile("asdf", OpenFileOptions{.flags = 0, .mode = 0, ...}); // OK
} (and a trailing comma after the This has advantages and disadvantages. When the reader sees the |
My reasoning in favor:
Against:
Decisions:
|
Doesn't this conflict with "The values must be |
I mean a logical dependency, not a literal dependency. Something like this: const S = struct {
action: FileAction = .Open,
flags: u32 = posix.O_READ | posix.O_EXCL,
}; Now if you do |
This seems like a reasonable take--I made almost all the same tradeoffs in my language with the exception of the |
I am sooo excited for this feature :) Mainly because I want to wrap my C cross-platform headers into zig interfaces, and those have been designed with C99 designated initialization in mind (many calls have desc-struct arguments, which sometimes have dozens of items, but usually only a few of them are differing from the default values). It's surprisingly hard to transfer this idea into other languages (often they work around the problem with builder functions, which is a lot of boilerplate). Here's an example C99 program, so you know what I'm talking about: |
\o/ |
This is great! What about setting the default values of fields of imported C structs to zero? This way one can initialize a C struct nearly the same way one would do in C: c: typedef struct {
int a;
int b;
} my_type;
my_type zero = my_type { 0 }; // a = 0, b = 0
my_type partial = my_type { .a = 1 }; // b = 0 zig: var zero = c.my_type { }; // a = 0, b = 0
var partial = c.my_type { .a = 1 }; // b = 0 As it is now, one must set all field values when initializing a C struct in zig. This quickly becomes cumbersome, especially if the C struct contains arrays. UPDATE: This was mentioned in #1031 but that was before default struct field initialization was accepted |
1 On having C structs use 0 as defaults for everything to make interop with C code more seamless. |
Since there is a proposal for default function arguments, I'm putting forward the idea of default initialization values in structs for the sake of completeness. Consider
I'll elaborate on some use cases later today.
The text was updated successfully, but these errors were encountered: