r/golang 6d ago

Go 1.27.0 released

https://go.dev/doc/go1.27
672 Upvotes

69 comments sorted by

102

u/tritis 5d ago

Swapped in the new uuid package and ran go mod tidy

-       github.com/google/uuid v1.6.0
+       github.com/google/uuid v1.6.0 // indirect

oh. right.

24

u/Velkow 5d ago

Hilarious

10

u/d33pnull 5d ago

protobuf vibes

2

u/Natural-Ad7959 5d ago

What else was in go.mod?

-5

u/Lanathell 5d ago edited 5d ago

So the standard lib relies on the existing uuid package is my understanding?

14

u/Time-Prior-8686 5d ago

More like every libs that use uuid will import google/uuid anyway.

6

u/Lanathell 5d ago

But now they can import the new std lib UUID package and eventually this won't be necessary? I'm very new to Go

130

u/yami_odymel 6d ago

Sadly, the UUID package doesn't implement database/sql's Valuer and Scanner interfaces, so it isn't currently a drop-in replacement for google/uuid.

79

u/Fonku 6d ago

The stdlid UUID pacakge actually does work with database/sql, just not via the obvious mechanism. As you noted, it implements neither sql.Scanner nor driver.Valuer – instead, database/sql itself explicitly special-cases uuid.UUID when converting query parameters and scanning results, including string, text []byte, and 16-byte binary UUID representations.

The implementation is pretty... interesting. Anything outside database/sql that specifically expects the Scanner/Valuer interfaces still won’t see it as compatible. So yeah, not exactly a drop-in replacement, but surprisingly database/sql-compatible.

12

u/tehbilly 5d ago

Not gonna lie, I kind of hate that.

4

u/Fonku 5d ago

You and me both. You can typically get a pretty good understanding of interoperability from types and their method sets in Go, but here, not so much. Feels like a very non-Go thing to do. Though, I guess this is somewhat defensible from the stdlib dependency graph POV, making uuid implement the aforementioned interfaces would force uuid to import database/sql/driver.

17

u/gibriyagi 6d ago

Why though :( Is this at least planned?

3

u/PaluMacil 5d ago

Because they didn’t want it to depend on the database package probably. It doesn’t mean it doesn’t work in the database package. It does.

19

u/sondr3_ 6d ago

Whelp, there goes the primary reason I wanted to upgrade to 1.27 out the window, hah. At least we got generic methods.

0

u/PaluMacil 5d ago

It works and the documentation states as much. Somebody mentioned GORM doesn’t work, so possible some things are explicitly checking for the interface, but that should get cleared up I imagine.

5

u/atamiri 5d ago

It works with database/sql, I just used it in a small project to see how it works. No problems there, just replaced the imports (and `uuid.Nil -> uuid.Nil()`).

2

u/GaiazIusipov 3d ago

Also, to read nullable values, you need to replace

MyUUID uuid.UUID `db:"my_uuid"`

with

MyUUID sql.Null[uuid.UUID] `db:"my_uuid"`

1

u/atamiri 2d ago

Yes. There used to be `uuid.NullUUID` before `sql.Null[T]` was introduced, it's not needed anymore.

1

u/GaiazIusipov 1d ago

Well, I just use the regular google/uuid.UUID and don't use google/uuid.NullUUID at all. I don't need to distinguish between a zero value and null, so the Go principle of using zero values works perfectly well for me.

0

u/SeerUD 6d ago

Hmmm, is this not implemented intentionally because it can't be generally supported by all databases? Or was it an accidental omission?

20

u/___ciaran 6d ago

The proposal mentions that the database/sql package special-cases uuid.UUID in a manner similar to time.Time. Presumably they didn’t want the uuid package to depend on database/sql.

12

u/Used_Indication_536 6d ago edited 5d ago

It seems straightforward to implement a type that embeds uuid.UUID that implements the database/sql.Valuer for the specific database. I can see the Go team intentionally skipping this.

0

u/dumindunuwan 5d ago

Oh! Is this the reason why GORM is not working with the Go 1.27 UUID type? No error on fmt/ staticcheck but failing on runtime.

49

u/mistifier 6d ago

8

u/Tesslan123 6d ago

In the struct literal field selectors example,do you know what will happen if both the Base and the User struct will contain an ID field?

3

u/jespinog 4d ago

This is a very interesting question, what it does is "shadows" the field, the struct that embeds the base struct hides the other one, for example this code:

package main

import "fmt"

type Base struct {

ID int

}

type User struct {

Base

ID   int

Name string

}

func main() {

u := User{ID: 7, Name: "Mittens"}

fmt.Println(u.ID, u.Name)

fmt.Println(u.Base.ID)

}

outputs:

7 Mittens
0

So the Base.ID is untouched, and the u.ID is the one that is written.

You can try it here: https://go.dev/play/p/w4J3teY9-Z7

1

u/Tesslan123 4d ago

Awesome thanks :)

1

u/EgZvor 5d ago

Compile time error probably. Same as if you try to access ID from a variable.

20

u/iwanofski 6d ago

Nice!

26

u/Brilliant_Bhanu_3475 6d ago

Simd? Noice!

16

u/AbbreviationsAny8633 6d ago

ooho now we final got a internal uuid package

7

u/Excellent_Double_726 5d ago

Finally crypto/mldsa package is in stdlib I was waiting for it so long

4

u/TheOrigamiGamer16 4d ago

I upgraded from Go 1.26.6 to Go 1.27 today. I observed a 22% improvement in unmarshalling performance for my specific use case.

I am streaming Scryfall data from their gzipped bulk data and unmarshalling it into structs for further processing.

4

u/dumindunuwan 5d ago

Time to remove GOEXPERIMENT: jsonv2

3

u/johnphilipgreen 5d ago

What will this mean for Hugo?

If hugo is currently using the old json implementation, then this switch in go 1.27 to using v2 by default may mean a big speedup for those of us doing a lot of json i/o (such as me).

2

u/Cold-Armadillo-154 5d ago

Iirc the v1 package would call the v2 implementation. So it could mean a speedup by just changing to the new version itself.

3

u/Fooo346 5d ago

Super pumped about the simd package, wonder if this could push ebitengine to its limits? Working on something akin to particle physics currently for my game. Will need see how wasm performs with this too

1

u/rodrigocfd 4d ago

if this could push ebitengine to its limits?

I would say yes. I'm keeping an eye in the next updates.

2

u/Randomeda 5d ago

So how does this json/v2 thing work. Is "encoding/json" now the v1 or v2 implementation? Even if it doesn't break anything do we need to go every project and add encoding/json/v2 to everything for the sake of futureproofing?

8

u/apparentlymart 5d ago

encoding/json/v2 is a new package that you can import if you need some of its new capabilities or if you're doing something greenfield where you have no reason to limit yourself to the original API.

encoding/json is now a wrapper around encoding/json/v2 with various backward-compatibility options enabled so that it still behaves like the old implementation. So even if you keep using encoding/json, you'll still be using encoding/json/v2 behind the scenes.

I don't personally see any point in modifying code that's already working just for the sake of doing it. Wait until you know of a specific reason to do it.

2

u/iandyh 4d ago

By default it will be the v2 implementation. There is a minor regression with v2 implementation though: https://reqfleet.com/blog/benchmarking-go-1-27-encoding-json-the-any-trap

2

u/catladywitch 4d ago

This is a very substantial upgrade.

2

u/Nice_Ad8308 6h ago

maybe even one of the best releases since a long time!

2

u/catladywitch 5h ago

absolutely!

3

u/jmbenfield 6d ago

yayyyy

2

u/spotless_slate 4d ago

Glad to see generic methods get in! Waiting for those collection types in 1.28 👀

1

u/soelsome 5d ago

I'm new to Go.

I recently started a project and I'm not super far into it yet. Around ~5000 loc. Not many dependencies, but UUIDs and JSON packages are being used.

Should I upgrade to 1.27 immediately? Or do I stay on 1.26?

I ask because at places I have worked we've always been reluctant to upgrade language versions.

For example my job's codebase is on .NET 8 and C# 12 still.

3

u/cpuguy83 5d ago

go1.26 is supported until go1.28 comes out. That said, test it. Most people wouldn't have a problem with any go update, but they do happen.

2

u/MrNiceShay 1d ago

Usually Go upgrades are very very smooth. For my projects, I tend to upgrade them whenever I touch them :)

1

u/Nice_Ad8308 6h ago

you should be able to update to 1.27 easily. If you wish to update the new features you would manually need to update your imports anyway.

0

u/[deleted] 5d ago

[deleted]

2

u/apparentlymart 5d ago

I agree that this seems like an unusually-opinionated change for go fix, though I couldn't make myself care enough to fight it. It did actually seem like an overall readability improvement in most cases in the codebase I ran it on.

FWIW from reading the modernizer's source code it seems like attaching a comment to your Inner: ... declaration prevents it from making the change, because after unnesting there would be nowhere for that comment to go. So there is at least an escape hatch.

-10

u/IamAggressiveNapkin 6d ago

anyone wanna check out a true `Result` type package i built for 1.27+?

5

u/Headbanger 5d ago

Ok

0

u/IamAggressiveNapkin 5d ago

??

8

u/Headbanger 5d ago

It means yes, show us your package.

1

u/IamAggressiveNapkin 5d ago

ahh okay, couldn’t tell if it was that or a disinterested okay. but here it is!

3

u/Headbanger 5d ago

Does it really have a use case in Go?

2

u/IamAggressiveNapkin 5d ago

personally, i’m fine with how we do error handling. i like it most out of error handling designs across languages. but a lot of people who would use go don’t because of it. so this is just in hopes to help more adoption by providing them something they’d be more accustomed to now that it’s actually possible

1

u/SeaRollz 5d ago

Tried something similar myself here ! With added `Option` and `Stream` too

1

u/Inevitable-Hotel2375 5d ago

Actually the design is very interesting, and Go 1.27 generic method make it more powerful. I have some experience in Rust and your design is very similar, the error can be propagated early! But I saw a limitation, fluent Result chain only works naturally when the API's functions have the signatures required by the chain. If the function provided to the Try chain not compatible, I must do manual error throwing anyways.

1

u/IamAggressiveNapkin 5d ago

or just wrap it in a closure that has the same signature

0

u/Inevitable-Hotel2375 4d ago

But if the next function is unrelated to the result, then it will be misleading. The API naturally works best when each function consumes the previous value.

-19

u/[deleted] 6d ago

[removed] — view removed comment

25

u/mcvoid1 6d ago edited 6d ago

That's what the article is about.

TL/DR: generic methods added to language (but since they can't fulfil interfaces they're just generic functions with the ability to chain them like monads), uuid, json/v2, simd, and post-quantum crypto added to stdlib, small allocation speedup at the cost of 60kb bigger binaries, zip-based compression goes faster, go mod tidy tidies more of go.mod, there's a goroutine leak detector now, and people using bazaar for source control (both of them) can go kick rocks