11 ms·
Go 1.10 Beta 1 is released
- shabbyrobe 9y agoThis release finally brings a way to raise an error when an unknown key is encountered in a JSON object: https://go-review.googlesource.com/c/go/+/74830 https://go-review.googlesource.com/c/go/+/74830 The error's text is close to useless for even a moderately complex JSON object, but at least it's possible to catch this condition now.
- jitl 9y agoThis is the improvement that I’m most excited about for this release. I waded through some code recently that implemented its own validation in a hacks way by text-digging the re-serialization of structs... We were unable to put default (zero) values in our config files...
- majewsky 9y ago> We were unable to put default (zero) values in our config files... Huh? I don't know the details of what you're (de)serializing, but the standard strategy for default values that are not zero values is to have unpack into a pointer. For example, if you have a message like { "foo": 23, "bar": 42 } and the "bar" field has a default value of 5, you unpack like: var msg struct { Foo int Bar *int } err := json.Unmarshal(data, &msg) //handle error if msg.Bar == nil { defaultValue := 5 msg.Bar = &defaultValue } If you cannot change the type of the message to have a pointer field, you can implement json.Unmarshaler for the receiving type such that UnmarshalJSON deserializes into a temporary type, then copies the values into the recipient: type Message struct { Foo int Bar int } func (m *Message) UnmarshalJSON(in []byte) error { var msg struct { Foo int Bar *int } err := json.Unmarshal(data, &msg) if err != nil { return err } m.Foo = msg.Foo m.Bar = 5 if msg.Bar != nil { m.Bar = *msg.Bar } return nil } Now you can deserialize into Message (or into a struct containing a Message or *Message or []Message or whatever) and it will fill in the correct default value.
- jerf 9y agoOne thing you may want to consider in the future, or, at least, whoever wrote that code, is that it's not that difficult to fork the standard library and make it do something different in your program. I forked the encoding/xml library once so I could add tag stack depth limits and size limits for tags and text nodes, so I could use it to write an XML validator (in which you must be careful that the user can not simply blow out your RAM by sending you too much text), and I forked encoding/json so that you could declare a map[string]interface{} field on an struct you are decoding into that will "catch" any unmatched keys in the JSON object and treat it the same as if you passed the map[string]interface{} in as the thing to decode into, instead of discarding them. (Encoding works too.) The first was on the order of two days and the second was on the order of four hours (untested in production, but the unit tests are fairly easy and comprehensive), though in both of those particular cases if you've not fiddled with the "reflect" package enough to understand it, you'll also need to pay that price. Other packages may require other knowledge, of course. But the time required is such that it may be less than the time spent on dirty, half-working hacks, which tends to grow from the "just five minutes" of the initial estimate to "five days and we're still paying for the hack five years later...".
- shabbyrobe 9y agoYou can have whatever default value you like by initialising the struct before you pass it to json.Unmarshal. If the key isn't present, it won't be set: type Test struct { Foo string Bar string } func NewTest() *Test { return &Test{Foo: "a"} } func main() { t := NewTest() if err := json.Unmarshal([]byte(`{"Bar": "b"}`), t); err != nil { log.Fatal(err) } fmt.Printf("%#v\n", t) } Output: &main.Test{Foo:"a", Bar:"b"}
- bpicolo 9y agoI wouldn’t recommend that against external APIs in general, though there are use cases. Adding keys is usually the best way to make backwards compatible changes in an API, but you’d make those changes backwards incompatible in your own infra.
- shabbyrobe 9y agoThat's a good point. It's more useful for config files than APIs I reckon. That's why I've been hanging for it.
- lobster_johnson 9y agoMy experience is that strictness is preferable here; silently accepting bad keys in a JSON object will lead the caller to think it's working, when it's not. If you then break the API's backwards compatibility by, say, removing a field, then your API will visibly break, which is correct, something you'd otherwise not detect. The solution to maintaining backwards compatibility is a combination of explicit versioning, erroring like this, good documentation, and trying to support old features for as long as possible. Definitely never liked Go's silent ignoring of JSON keys. The workarounds (e.g. overriding the unmarshal code to apply a check) have always been very invasive. Edit: Maybe you meant in the client, since you wrote "against". If so, I would still argue that strictness is good, as you do want your client to break (or at least warn) if something changes.
- bpicolo 9y ago> If you then break the API's backwards compatibility by, say, removing a field, then your API will visibly break That's a different issue. Fields going missing is definitely something I want to cause big problems. I do mean consumers (e.g. unmarshalling JSON responses from APIs), as the typical mechanism to support backwards compatibility is by adding keys. Otherwise you can't upgrade ever without entirely new API versions, and you force lockstep for deployments. Needing new data is a common thing - maybe you have user endpoint that's not returning <some_flag> that you added that you now want in some new service. Bumping APIs for every added field would get unwieldy fast and you'll have services scattered among many API 'versions'. It's just like in protobuf. In protobuf (or most other service-to-service serialization libs), adding a new field is not backwards incompatible.
- 59nadir 9y ago> There is no longer a limit on the GOMAXPROCS setting. (In Go 1.9 the limit was 1024.) Why was there ever a limit? Is anyone in the know on this?
- shabbyrobe 9y agoLooks like it was because an internal structure in the runtime had a fixed size, but that has changed: https://stackoverflow.com/questions/40943065/golang-why-runtime-gomaxprocs-is-limited-to-256 https://stackoverflow.com/questions/40943065/golang-why-runt... https://github.com/golang/go/commit/ee55000f6c45d2f5c38d91679def933fdf27c029 https://github.com/golang/go/commit/ee55000f6c45d2f5c38d9167... https://github.com/golang/go/issues/15131 https://github.com/golang/go/issues/15131
- delta1 9y agoRelease notes link: https://beta.golang.org/doc/go1.10 https://beta.golang.org/doc/go1.10
- bsaul 9y agoI don’t see anything regarding vendoring. What’s the current official tool for managing dependencies ?
- Aissen 9y agoThere's no official tool (yet). The community seems to push dep as a future official tool though: https://github.com/golang/dep https://github.com/golang/dep
- lobster_johnson 9y agoDep is very nice. We've been using Glide for more than a year, but it's incredibly buggy/flaky and has several ugly misbehaviours. Dep isn't finished, but it's already better than Glide, and we're transitioning over to it.
- azinman2 9y ago> For the X86 64-bit port, the assembler now supports 359 new instructions, including the full AVX, AVX2, BMI, BMI2, F16C, FMA3, SSE2, SSE3, SSSE3, SSE4.1, and SSE4.2 extension sets. The assembler also no longer implements MOVL $0, AX as an XORL instruction, to avoid clearing the condition flags unexpectedly. Is x86 vector support only being added now? https://www.youtube.com/watch?v=gso3g_ofjlw https://www.youtube.com/watch?v=gso3g_ofjlw
- cdoxsey 9y agoThe go assembly language is a bit idiosyncratic and didn't include all instructions, which led to https://golang.org/doc/asm#unsupported_opcodes https://golang.org/doc/asm#unsupported_opcodes . The standard library is actually chock full of specialized assembly implementations of various algorithms. Well worth a look even if you don't use Go. Here's an example of aes encryption which is a relatively recent instruction: https://golang.org/src/crypto/aes/asm_amd64.s https://golang.org/src/crypto/aes/asm_amd64.s
- sjellis 9y agoFrom the release notes, arguably the best feature: "There are no substantive changes to the language." Seriously, Go is not a perfect language, but I have come to really appreciate the stance that the Go team have taken on stability. Looking forward to Go 2, but very happy to keep on with Go 1.
- issaria 9y agoYeah, good luck getting generics.
- golergka 9y agoI don't know why you're downvoted. Generics is a feature that's holding back a lot of developers dealing with complicated business logic (and need for abstraction) from moving to Go. And at the same time, including generics into the language means that all libraries will add generics interfaces - and most probably, stop supporting the old, non-generic interfaces in some time into the future, breaking backwards compatibility at some point.
- _ph_ 9y agoI am one who downvoted that statement, because I considered it a snippy remark without any content. Especially, as the question of generics in Go has been mentioned and discussed often enough. And if one feels the need to restart that discussion with each Go release, one should do so with an insightful comment. I do not agree with your comment. I don't see how generics are needed to deal with "complex business logic". Yes, ultimately I would like to see generics added to the Go language. As does the Go development team. But, as they have clearly laid out, this is not a trivial undertaking. There hasn't yet been an implementation concept presented, which fits into the Go framework with its design goals. And until then, I am quite happy that they didn't implement some half-finished concept.
- pjmlp 9y agoAdding generics to Java and C after several years, shows how successfully the "wait and see" actually works, versus languages that have supported them from the get go. CLU was designed in 1975 and ML in 1973, several languages with support for some kind of generics have been born and died since then. So in 42 years, there wasn't a single generic implementation that could fit Go's design goals, other than not having generics at all?!
- dis-sys 9y agoTried my consensus library in go, and it is now 5% faster AGAIN. I like such magic. ;) What I am really looking forward to is the NUMA awareness in the runtime. Most servers are now NUMA machines, in fact AMD Threadripper is NUMA and it costs a few hundred $ only.
- qrv3w 9y ago> The go get command now supports Fossil source code repositories. Neat! I've been waiting for this.