-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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: spec: option types #7054
Comments
Having to deal with json and multiple database backends (not just sql), the lack of true optional types has been by far the biggest pain point in adopting Go. Not having it means the API surface increases in many places at the application level to compensate. Providing real optional types at a language level would make it much more convenient, and safe, without requiring developers to increase the API surface by repeatedly having to write custom types for the same case. I don't know about implementation, but something closer to Option 2 above would be incredibly beneficial. I don't use Swift, but the way that language expresses the idea of optionals seems consistent, convenient and safe. You declare any type as optional, and when you access it, it must be unpacked properly, so it's clear at compile time whether or not the operation is safe. The ability to chain those operations is icing on the cake. |
I have in the past almost exclusively used pointers to skip fields on (de)serialization because they work well with omitempty; if they are nil, the field doesn't get written, if it has value it gets written even if it's the zero value for the type pointed at. But that gets really painful for fields that are type S struct {
F0 *int `json:"f0,omitempty"`
F1 *int `json:"f2,omitempty"`
...
} When I have a struct like the struct like the above, I can't inline define the int values because it's not possible to get a pointer to a constant, or it may not be desirable to take the pointer of where the int value currently lives and doing so may actually introduce problems. So I repeatedly end up with many extra vars as a temporary place to copy the value, or a function to turn an int value into a pointer. e.g. https://play.golang.org/p/fb-9w9_vOU Another problem I've found is when I use pointers in this way it feels like I'm misusing them and misscommunicating intent. I usually want a value type, and just want to indicate it's not set which is different to wanting to point to a value being stored somewhere else. Because the fields are pointers to other fields it's always possible I introduce bugs when using the pattern above by accidentally pointing to a value that changes underneath me. I think something like optionals could make it easier to express that intent and prevent errors with pointers when pointers are not needed. To counter my own argument, I could also see myself overusing optionals when a default value would be simpler, and I've seen Java code get too interesting with it's use of Optionals and hope that wouldn't become the norm in Go code. As an experiment I wrote an |
Related to #19412. This proposal looks like a special-case of general sum types. Based on some proposed syntax in that issue, this may take the form: type Message struct {
Name nil | string
Title nil | string
Message nil | string
Date nil | time.Time
} However, this would not be as nice since since a type assertion would still be required to switch on the exact type. EDIT: Some of the proposals in that thread would allow this to be nicely represented where the "non-set" state is the zero value, but provides a way to distinguish whether it was actually set or not. I support a sum-type solution that solves this well rather than this being a standalone feature. |
That makes sense... how would accessing those properties work in practice, via type assertions maybe? Building on your example, something like: m := Message{Name:"Foo"}
if name, ok := m.Name.(string); ok {
fmt.Println(name)
}
if title, ok := m.Title.(string); ok {
fmt.Println(title)
} In that case, |
@evillemez, it really depends on the exact specification of how sum types works. The proposal in #19412 has been active and there have been various proposed specifications. Some of which work better than others in acting as an "option" type. I suggest you participate in the discussion over there. |
There is a lot more discussion over on #19412 for a general approach to this problem. I'm going to close this issue in favor of that one. |
The text was updated successfully, but these errors were encountered: