Go 1.27 interactive tour<br>Skip to content
Products
Toggle Products submenu<br>VictoriaMetrics<br>VictoriaLogs<br>VictoriaTraces
VictoriaMetrics Enterprise<br>VictoriaMetrics Cloud<br>Anomaly Detection
Plans & Features<br>Resources
Toggle Resources submenu<br>Community<br>GitHub Repos<br>Documentation<br>Blog<br>Case Studies<br>Security<br>๐ฑ Sustainability
Support
Toggle Support submenu<br>Enterprise Support<br>Community Support
About Us
Toggle About Us submenu<br>The Team<br>Careers<br>Customers<br>Partners<br>News & Articles<br>Contact Us
Contact Us<br>Book a Demo
รBook a Demo
๐ก๏ธ<br>Embedded widget blocked<br>Your privacy settings or an extension blocked the booking widget.<br>Open booking page<br>If you use a blocker, allow embeds for this site and try again.
Blog
/Go 1.27 interactive tour
Go 1.27 interactive tour<br>Go<br>Share:
Go 1.27 is coming soon, so it’s a good time to get a head start on what’s new. The official release notes are pretty dry, so here’s a hands-on version with runnable examples showing what changed and how the new behavior works.<br>A quick credit first: the interactive Go tours were started by Anton Zhiyanov, who wrote one for every release from Go 1.22 through Go 1.26. He’s decided to stop, so we’re picking up where he left off. His earlier tours are all still worth a read:<br>Go 1.22 interactive tour<br>Go 1.23 interactive tour<br>Go 1.24 interactive tour<br>Go 1.25 interactive tour<br>Go 1.26 interactive tour<br>Thanks, Anton.<br>Before we start digging into the new features, let’s set the context.<br>This article is based on the official release notes and the Go source code, licensed under the BSD-3-Clause. This is not an exhaustive list; see the official release notes for that.<br>Links point to the documentation (๐), proposals (๐ฃ), most relevant commits (๐๐), and authors (๐) for each feature; check them out for motivation, usage, and implementation details. The authors (๐) are the people who contributed to the feature (writing the implementation, the tests, or, for features that graduated from an earlier experiment, the original design), not necessarily a single main author.<br>Error handling is often skipped to keep the examples short. Don’t do this in production ใ<br>Generic methods<br>This is the headline of the release. A method declaration may now declare its own type parameters, independent of the receiver’s. Before Go 1.27, only top-level functions could be generic, so a generic operation on a type had to live as a package-level function instead of a method.<br>Say we have a generic container and want a Map operation that can change the element type:<br>type Box[T any] struct{ v T }
// The method declares its own type parameter U (new in Go 1.27).<br>func (b Box[T]) Map[U any](f func(T) U) Box[U] {<br>return Box[U]{v: f(b.v)}
Now Map is a method of Box and can transform an int box into a string box:<br>func main() {<br>b := Box[int]{v: 21}<br>doubled := b.Map(func(n int) int { return n * 2 })<br>label := doubled.Map(func(n int) string {<br>return fmt.Sprintf("value=%d", n)<br>})<br>fmt.Println(label.v)
value=42
There is one important restriction: interfaces still can’t declare type-parameterized methods, and a generic method can’t be used to satisfy an interface. Put a generic method in an interface and the compiler stops you:<br>type Mapper interface {<br>Map[U any](f func(int) U) any // interfaces can't declare generic methods
interface method must have no type parameters
๐ Generic methods<br>๐ฃ 77273<br>๐๐ 524b860, e84da04, e212a16<br>๐ Robert Griesemer, Mark Freeman<br>Struct literal field selectors<br>A key in a struct literal may now be any valid field selector for the struct type, not just a top-level field name. In practice this means you can set a promoted field (one that comes from an embedded struct) directly, without spelling out the embedded type.<br>type Base struct {<br>ID int
type User struct {<br>Base<br>Name string
Before Go 1.27 you had to write User{Base: Base{ID: 7}, Name: "Mittens"}. Now the promoted ID works as a key on its own:<br>u := User{ID: 7, Name: "Mittens"}<br>fmt.Println(u.ID, u.Name)
7 Mittens
๐ Composite literals<br>๐ฃ 9859<br>๐๐ 1a8f9d8, 9f7e98d, 30bfe53, e2c1885<br>๐ Robert Griesemer, Cherry Mui<br>Generalized function type inference<br>Function type inference has been generalized to apply in all contexts where a generic function is used where a matching function type is expected: not just plain assignment to a variable (which already worked), but also conversions and composite literals. In those cases you previously had to spell out the type arguments by hand.<br>Take two generic helpers and drop them into a slice whose element type is func([]int) int:<br>func first[T any](s []T) T { return s[0] }<br>func last[T any](s []T) T { return s[len(s)-1] }
// The slice's element type drives inference: T=int for each entry.<br>// Before Go 1.27 this failed with "cannot use generic function<br>// without instantiation"; you had to write first[int], last[int].<br>ops := []func([]int) int{first, last}<br>for _, op := range ops {<br>fmt.Println(op([]int{10, 20,...