1. 51
    1. 12

      I really enjoyed the interactive snippets for comparing the different language versions. Very clever and well-executed!

    2. 5

      HTTP routing in the standard library is now more expressive

      I likely won’t switch away from chi and friends (common routing libs in Go) for the “main” routing, but I write a lot of small http servers in tests (to mock a vendor, for example), and this will make that a lot easier to do.

      1. 3

        Honestly for small apps I don’t even use the standard router; I just use a bunch of regexes and the first one that matches gets dispatched to. It’s extremely simple, so much so that I don’t even bother putting it in a library. The only real downside is that regexes can be a little tedious/error-prone.

    3. 4

      Previously, the variables declared by a “for” loop were created once and updated by each iteration. … In Go 1.22, each iteration of the loop creates new variables, to avoid accidental sharing bugs

      Doesn’t this change the semantics of the language? As in, code that used to compile and run, now still compiles but does something different. How are you supposed to handle this as a developer or a user?

      1. 12

        In this announcement they say the new semantics will only apply to modules with go 1.22 declared in go.mod. I remember Perl doing something similar (use 5.12.0 in a file enables some backwards compatibility breaking stuff), and Rust has the edition system for this which IMO feels more explicit to opt into since it’s not tied to compiler version.

      2. 10
      3. 6

        Yes, but it is far more likely that this change in behavour fixes a bug than causes it, so they decided to make this change.

      4. 4

        First, you have to opt-in to the new semantics by increasing the go version in go.mod, and second, all of the examples I’ve seen that break with the new semantics are highly contrived code examples that haven’t been seen organically in the wild. Maybe there are legitimate examples out there, but I’ve never seen them, and for those, the opt-in requirement is good enough to avoid unexpected breakage.

    4. 4

      Very cool. I feel like cmp.Or handles a common enough case that it’s worth writing up too. I wrote it though, so I’m biased.

      1. 2

        I’m looking forward to this. I have one of these functions is several projects.

    5. 3

      Functions that shrink the size of a slice (Delete, DeleteFunc, Compact, CompactFunc, and Replace) now zero the elements between the new length and the old length.

      Looking at the examples on the page, this one confused me initially. The examples are slices of int, and in that context, I couldn’t see why anyone would care about zeroing out the ints “between the new length and the old length.” But when you look at the docs for the current implementation of slices, you find this: Delete might not modify the elements s[len(s)-(j-i):len(s)]. If those elements contain pointers you might consider zeroing those elements so that objects they reference can be garbage collected. I suppose that the new implementation just follows their own advice across the board.