-
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: strconv: Add Parse[T] #57975
Comments
Wouldn't this have to use a big type switch internally? How often does this come up that it needs to be in the standard library? |
Yes.
I've needed it about 3 times now. Writing that big type switch is very tedious. |
I don't think a single v64, err := strconv.ParseInt(str, 10, 0)
// Check error.
v := int(v64) // Can't do the conversion inline with the call above. That's quite annoying, but it's relatively minor. If generics get default types or something, it would be nice to see those functions made generic so that I could just do |
\cc @josharian. Seems similar to his |
I tried a different implementation of The most relevant part: func Parse[T Parseable](str string) (T, error) {
var result T
_, err := fmt.Sscanf(str, "%v", &result)
return result, err
} I don't think it would be possible for this specific implementation to live in It feels perhaps like what With all of that said, I'm also not feeling super convinced about this being in stdlib. This |
I had no idea you could use |
I am against “useless uses of generics.” The signature should be |
Hmm indeed and further to @carlmjohnson's point, if a proposal like #57644 were accepted then it could become possible to use a sealed type set for an interface value. If the implementation is going to immediately wrap the given value in With that said, I can see the attraction of a form that returns a value rather than writing through a pointer. It tends to lead to (subjectively) more "normal-looking" code. But for a case like this I'm not sure it is worth it, especially since "write through a typed pointer" is already the typical API style for unmarshal-like functions in Go. |
@apparentlymart The assumption is that the overhead will go away once we have something like #45380 |
If #45380 existed, this would not be a "useless use of generics", but for now at least, it doesn't and best practices documents specifically call out not using generics for deserialization. Also, maybe I'm idiosyncratic, but I try to arrange my generic functions so that the type inference means I rarely if ever need to explicitly use a type specifier. That means I prefer All that said, I too have written a function like this before, so it's clearly something users want, whether we should or not. :-) |
Link? (not disagreeing, just curious). |
https://go.dev/blog/when-generics
|
Any time I've ever needed a function like I don't think the need for this exact function is general enough to warrant inclusion in the standard library. |
Given the discussion, I think I'd like to alter the proposed function to something like this: func Parse(s string, v any) error This would be functionally equivalent to: func Parse(s string, v any) error {
_, err := fmt.Sscanf(str, "%v", v)
return err
} |
|
|
This really seems like an unnecessary use of generics. Unifying parsing of quoted strings and floating point numbers into a single function makes no sense. |
For numeric types, such function would be useful. It may help to avoid some overflow/conversion bugs like this // Example from https://codeql.github.com/codeql-query-help/go/go-incorrect-integer-conversion/#id1
func overflowBug(wanted string) int32 {
parsed, err := strconv.ParseInt(wanted, 10, 64)
if err != nil {
panic(err)
}
return int32(parsed)
}
func useParse(wanted string) int32 {
parsed, err := strconv.Parse[int32](wanted, 10)
if err != nil {
panic(err)
}
return parsed
} |
I think a convenience function like |
Having an int-generic strconv might also help with 128 bit ints: #9455 (comment) |
From a pure API perspective, yes. But as I wrote in the atox readme: "It is mainly helpful when you are writing other generic code that needs to parse number out of strings." Generics can be viral in this way, and using them with the entirely non-generic standard library can cause a frustrating impedance mismatch, which is how atox started: I wanted to write that repetitive, uninteresting, error-prone reflect switch wrapper code only once.
Fair. I didn't put too much thought into the atox API, I just solved the problems I had. Again, though, I suspect you'll end up with people writing repetitive reflect-based wrappers around it anyway, which is the pain that this is trying to prevent. |
Rust support trait based polymorphism, for example: std::convert::Into, it support a type implements a trait multiply times, the difference each time is the type parameter. It is regrettable, in go, no indication that the core team is interested in this, although it's useful in many places and improves code readability. |
This proposal has been added to the active column of the proposals project |
Based on the discussion above, this proposal seems like a likely decline. |
No change in consensus, so declined. |
I'd like to propose a generic interface to the parsing functionality provided by
strconv
.This would mainly be used from other generic functions. For example:
The text was updated successfully, but these errors were encountered: