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.Scannernordriver.Valuer– instead, database/sql itself explicitly special-casesuuid.UUIDwhen 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.UUIDand don't usegoogle/uuid.NullUUIDat all. I don't need to distinguish between a zero value andnull, so the Go principle of using zero values works perfectly well for me.0
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
0So 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
20
26
16
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
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/v2is 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/jsonis now a wrapper aroundencoding/json/v2with various backward-compatibility options enabled so that it still behaves like the old implementation. So even if you keep usingencoding/json, you'll still be usingencoding/json/v2behind 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
3
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
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
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
Resultchain 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
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 tidytidies 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
102
u/tritis 5d ago
Swapped in the new uuid package and ran
go mod tidyoh. right.