-
Notifications
You must be signed in to change notification settings - Fork 18k
encoding/json: should try to convert strings<->numbers without errors if it's possible #22463
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
Comments
|
@cznic how is it relevant to my proposal? I guess you read this issue too briefly and missed a point. My point is To be clear, database/sql works already the same way var idStr string
db.QueryRow("select id from categories limit 1").Scan(&idStr)
fmt.Printf("%+v\n", idStr)
var idInt int64
db.QueryRow("select id from categories limit 1").Scan(&idInt)
fmt.Printf("%+v\n", idInt) Both |
I'm not convinced that this has a place in Many features and enhancements to This issue is also proposing a non-trivial design change to a package, so I would strongly recommend writing a proposal: https://github.com/golang/proposal |
My point is that it should better not do that. What numbers are the obviously expected results for strings like |
For these particular examples and Go's
That's because "...octal and hexadecimal formats are not used" in JSON For |
Being precise about whether a value is a number or a string is a feature, not a bug. But if you find yourself in this situation, it should be possible to write your own value types for these ambiguous fields, have them implement json.Unmarshaler, and add whatever semantics make sense for your application. That's the extensibility hook that encoding/json expects users to make. Extending the app itself scales much better than putting every customization like this into the main package. Please try that. |
Trying to combine api/JSON/databases in Go is a pain. The problem is it's very hard with JS applications/frameworks to be sure about the correctness of JSON output. Most probably everyone ends up with something like this:
Go could help a lot in this cases and the code above could be avoided, because Go has all the information needed to correctly convert, for example, this JSON
{"id": "1", "price": "100"}
into this structure... but instead of that it panics
Even more, there is a
json.Number
type which partially solves the problem, but still you should do a lot of checks and conversions (likeproduct.id.Float64()
) because it's not a basic type and alsodatabase/sql
doesn't support it.The only way I found to deal with this stuff is to create a new type, based on int64, and implement
json.Unmarshaler
interface. But it's still a lot of typing and error proneThe full example about what time-saving encoding/json could do out of the box (maybe with some flags to not break an existing code)
In my opinion,
err
shouldn't benil
only in case whenProduct.id
can't be converted toint64
,Product.price
tofloat64
and so on. The client code shouldn't be aware of what internal types are we usingAlso the same should be true about this case:
Go has enough information to assume that we want to convert JSON number
123
to Go's string, because it's the only reasonable case and JS client code shouldn't be bothered what's ourid
's internal type. But instead it panicsIf encoding/json could behave like this, it would make working with JSON in Go much more pleasant and concise
UPD: Actually it's not a cool feature, It's more like an obvious expectation. For example, database/sql works as expected with this
idStr
will be"1"
andidInt
will be1
(for example). Sojson
should follow the same logicWriting custom types with custom MarshalJSON/UnmarshalJSON isn't trivial and working with custom types isn't a pleasure at all. Also casting
js
code (id = +id
) or writingstrconv.Atoi()
for every json input is annoying.As a +1 for this proposal, there is a
json.Number
type and astring
tag. I assume they were created exactly for such kind of cases. But they don't work and look like a hack. With the behavior, explained above, there will be no need of them. At least when dealing with JS api clientsAs a +2, this behavior can save a lot of time for backend and frontend developers. Golang is a typed language, why not to use it at full strength?
The text was updated successfully, but these errors were encountered: