-
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: Go 2: Array or variadic destructuring to discrete variables #56094
Comments
For the particular use case you mentioned, why would you not just use a struct instead of variadic parameters? type ExtParam struct {
Size uint8
Scale uint8
Prec uint8
} This has the side benefit of improving clarity on the caller side, as people don't have to figure out which parameter is which anymore. |
It also allows them to be different types and have clearly defined definitions for one being unset. |
You're right, it could be coded like that by adding a struct next to the value argument. But then I needed the The idea of the proposal came as I tried to handle the omitted arguments. I just thought it would be great if we have a PHP-styled destructuring |
I feel like your new code looks so much shorter than your old code because you left out a bunch of lines that would have been repeated. Also your new code implies that the values are being set to a pointer type, as you are comparing them to |
I'm not clear what specifically type ExtParam struct {
value interface{}
size uint8
scale uint8
prec uint8
}
type ExtParamOption func(*ExtParam)
func WithSize(size uint8) ExtParamOption {
return func(p *ExtParam) { p.size = size }
}
...
func NewExtParam(value interface{}, opts ...ExtParamOption) ExtParam {
extParam := ExtParam{value: value}
for _, opt := range opts {
opt(&extParam)
}
return extParam
} Then the caller looks like: NewExtParam(value, WithSize(1), WithScale(2), WithPrec(3)) All of that aside, I would think your original proposal can be satisfied with a simple helper function like so. func getOrDefault[T any](x []T, i int, d T) T {
if i >= len(x) {
return d
}
return x[i]
} And then in your code sample it would be: size := getOrDefault(opts, 0, nil)
scale := getOrDefault(opts, 1, nil)
prec := getOrDefault(opts, 2, nil) |
The new code would not be checking for the range of the array, but on the value itself: if pr != nil {
switch t := pr.(type) {
case string:
if size64, err := strconv.ParseInt(t, 10, 32); err == nil {
prec = uint8(size64)
}
case int:
prec = uint8(t)
case uint8:
prec = t
default:
prec= 0
}
}
I was assuming the |
This technique is awesome! I will definitely use it in my succeeding projects. The ExtParam returns just as your defined struct type with a little difference: type ExtParam struct {
Value interface{}
Size int
Scale uint8
Prec uint8
} I intend to use this a new data type for SQL query parameters, so I didn't think of having helper functions to sanitize user data. I only thought of a constructor for readability and ease of use.
This is definitely helpful. About the proposal, this is my only use case yet. |
Besides the discussion above, there seems to be an ambiguity here: if you have a slice of In general there are other ways to do this, and based on emoji voting there doesn't seem to be much enthusiasm for this approach. Therefore, this is a likely decline. Leaving open for four weeks for final comments. |
No further comments. |
Author background
I consider myself as novice to intermediate Go programmer. I have no extensive experience of looking at established Go code under the hood.
I have VB, C# and PHP experience before becoming interested in Go.
Related proposals
Has this idea, or one like it, been proposed before?
I'm not sure. I searched the proposals and I can't find a proposal that discussed the same.
Does this affect error handling?. I'm not sure.
Is this about generics? No.
Proposal
I would like to suggest a language change that can execute dynamic assignments to a list of discrete variables.
I have the following code:
The
opts
variable is a variadic parameter in a function:In order to check if one or more of the values have been set, I need to check the length of the
opts
variable in order to enter and process the value further. As you have noticed, there is no null checking yet.It would be nice if we can destructure an array or a variadic variable like the one below:
And then we can write the following check if the value is null or not.
It can help developers to simplify their code
Please describe as precisely as possible the change to the language.
What would change in the language spec?
Please also describe the change informally, as in a class teaching Go.
The mechanics can be as follows:
Is this change backward compatible?
Show example code before and after the change.
Orthogonality: how does this change interact or overlap with existing features?
Is the goal of this change a performance improvement?
Costs
I think it will contribute to a more idiomatic Go concept. Instead of manually checking the length and indexing an array like the code I gave above, a quick and easy assignment like this would lessen the clutter.
PHP has the
list
function. It made the values retrieval easy to code and understand.The text was updated successfully, but these errors were encountered: