A Weak Connection Is Still A Connection • The Applied Go Weekly Newsletter 2025-01-26
Your weekly source of Go news, tips, and projects
A Weak Connection Is Still A Connection
Hi ,
Pointers have a strong effect on memory management: As long as there is any pointer still pointing to a heap-allocated object, this object cannot be garbage-collected.
There are, however, situations where it is absolutely OK if an object goes out of existence while pointers still reference it.
The new weak
package in Go 1.24 introduces weak pointers that do not prevent garbage collection and automatically turn into nil
once the pointed-to object is about to be garbage-collected.
I explored how this works in detail; more on this in the Spotlight section.
But first, some goodies from the Go space!
Featured articles
Mind The convT
Interfaces are indispensable. Yet, when performance is at stake, it's time to remove them and hardwire everything.
I made an online PS1 game and connected it to a PS4 - YouTube
So, this video is, like 99% about how to connect a PS4 LAN port to a PS1 serial (cereal?!) port, but at 11:00, the connection to Go suddenly becomes apparent. (Repos linked below the video.)
All releases - The Go Programming Language
Go 1.23.5 is out. The two most important updates are security fixes: "net/http: sensitive headers incorrectly sent after cross-domain redirect", and "crypto/x509: usage of IPv6 zone IDs can bypass URI name constraints"
[security] Go 1.24 Release Candidate 2 is released
Related to the release of Go 1.23.5, release candidate 2 of Go 1.24 contains the same two security fixes and two more: a fix regarding a GOAUTH credential leak and another one addressing a ParsePKCS1PrivateKey panic with partial keys.
Podcast corner
🌲🌳🌲 If an error falls in forest, and there's no variable around to see it... ?
Proposals for making Go's error handling syntax more concise are a dime a dozen. Now there's another one. Should we care? Mmm, perhaps we should, as the creator is none less than Ian Lance Taylor, a member of the Go team. Jonathan and Shay discuss this, and more, in this week's episode.
Spotlight: weak pointers
Which is the most-wanted feature of Go 1.24? I have no idea! However, weak pointers are a hot candidate.
What is a weak pointer?
Go uses garbage collection to make memory management convenient. If you create a pointer to data, Go may create the data on the heap if required. Once no more pointers point to a piece of data on the heap, the garbage collector can reclaim the memory used for the data.
However, what if you need a pointer that doesn't keep the pointed-to object from being garbage-collected?
This doesn't seem to make sense. A pointer that survives the data it points to? After all, if the data gets collected, that pointer would be invalid!
At a second glance, you can indeed find valid use cases, such as:
- A cache that caches objects only as long as there is at least one pointer pointing to it. Such a cache helps to avoid duplicate data, similar to the
unique
package. - Observe objects to track specific metrics throughout their lifetime.
Weak pointers allow for a straightforward implementation of such use cases.
How to use weak pointers
Theory is dull and grey, so let's turn to an example.
Prompt: Act as a game developer. You want to track characters inside the game, without preventing garbage collection if the player exits the game.
You: No problem, here is my tracker!
The game defines a Character
with a Position
:
type Character struct {
name string
position Position
}
type Position struct {
x, y int
}
A map of weak pointers to Character
keeps track of the characters in the game. Method Track()
adds a character to the map. A Remove()
method is omitted for brevity.
Method Track()
calls weak.Make()
to create a weak pointer from a *Character
and adds it to the map:
type LastSeenTracker map[string]weak.Pointer[Character]
func (t LastSeenTracker) Track(c *Character) {
t[c.name] = weak.Make(c)
}
Method GetPosition()
first checks if the given character name exists in the map. Then, it attempts to turn the weak pointer from the map into a normal pointer by calling the weak pointer's Value()
method.
Value()
returns a valid pointer to the object until the object is scheduled for garbage-collecting. In this case, Value()
returns nil
.
GetPosition()
converts the result of Value()
into the classic "value, ok" idiom:
func (t *LastSeenTracker) GetPosition(name string) (Position, bool) {
if wp, exists := t.characters[name]; exists {
if c := wp.Value(); c != nil {
return c.position, true
}
}
return Position{}, false
}
Func main()
simulates a character that leaves the game by creating a new scope for the character variable hero
. A new tracker tracks the character's position once inside and once outside the scope.
A call to runtime.GC()
ensures the character variable is collected on time (to avoid any "demo effect"):
func main() {
tracker := NewLastSeenTracker()
// Create a new scope to limit character lifetime
{
// Create a character that will go out of scope
hero := &Character{
name: "Hero",
position: Position{x: 10, y: 20},
}
// Start tracking the character
tracker.Track(hero)
// We can get the position while the character exists
if pos, ok := tracker.GetPosition("Hero"); ok {
fmt.Printf("Hero is at position (%d, %d)\n", pos.x, pos.y)
}
// hero goes out of scope here
}
// Force garbage collection
runtime.GC()
// Try to get position after character is collected
if pos, ok := tracker.GetPosition("Hero"); ok {
fmt.Printf("Hero is at position (%d, %d)\n", pos.x, pos.y)
} else {
fmt.Println("Hero is no longer in the game")
}
`
Run the full code on the Go Playground, or—spoiler alert!—see the code's output here:
> go run .
Hero is at position (10, 20)
Hero is no longer in the game
Bottom line: It's ok to be weak.
Quote of the Week: Digits
In the digital age, don't forget to use your digits!
(Really. Do something with your hands for a change. Sketching, writing (including calligraphy), pottery, music, woodworking, playing with Lego... the possibilities are endless.)
More articles, videos, talks
Generic Adapters for MongoDB: A Go Solution Inspired by Rust
Interfaces between systems suffer from "impedance mismatch": data types require conversion when passing system boundaries. Example: databases and applications. Specific example: MongoDB and Go. The official MongoDB driver for Go requires a data decoding step that isn't type safe. Jimmy Nelle borrows some ideas from Rust's MongoDB driver to build a type-safe, generics-based alternative.
Make an MMO with Godot 4 + Golang - YouTube
Do you plan to write a massive multiplayer online game with Go and Godot? Expect to invest blood, sweat, and tears. Or invest some time in watching this free 13-part video course for a head start.
Gliter - async patterns in Go
Go's concurrency system is genius in its simplicity. Yet, large and complex scenarios need more powerful concurrency idioms. Aaron Hough suggests a generator/iterator system for constructing concurrent data processing pipelines: Gliter.
GopherCon 2024: Go in the Smallest of Places - Patricio Whittingslow - YouTube
Run Go in places where Go was never meant to run. Patricio Whittingslow demonstates how to turn an LED on with TinyGo... and some more dangerous things.
SQL Transactions in Go: The Good Way | Thibaut Rousseau's Blog
Wait, is there a bad way, too? According to Thibaut Rousseau, there is. Specifically, the bad way is to use DB transactions above the storage layer, thus creating a dependency on the DB implementation.
But what does Go have interfaces for? Right: for injecting dependencies without leaking implementation details into higher layers.
Meet the Transactor interface.
Awesome-templ Repo is looking for cool projects in the go/templ ecosystem
Are you an a-h/templ
user? The maintainers of awesome-templ
are looking for go/templ
projects to add.
How to Write Better Tests in Go
No, this is not a how-to about a new test strategy or technique. Rather, Jakub Jarosz argues that writing good tests requires a right mindset, and he suggests using the Four-Question Framework (designed for threat modelling) to create a mental model for building a testable Go package.
Projects
Libraries
GitHub - go-gum/unravel: Unravel provides Unmarshal functions that work with an abstract source data model.
If you hear "unmarshal", do you think "JSON"? unravel
removes any limitation from the unmarshalling process—map any data you want to Go structs.
GitHub - alexadamm/jwt-vault-go: JWT implementation with HashiCorp Vault's signature
Designing and building a JWT key signing system is not for the faint of heart, so consider yourself lucky that Alexander Adam did it for you.
Tools and applications
GitHub - Mdhesari/kian-quiz-golang-game: KianQuiz Game.
A two-player quiz game.
GitHub - madalinpopa/go-bookreview: Go-BookReview: A Simple App to Track Books and Notes
You get much more out of the (not-fiction) books you read if you take notes and keep them handy for later reference. This Web app is a book reading tracker and notetaker that helps you organize your reading notes.
GitHub - umegbewe/dhcpd: A fast, reliable DHCP server in Go
Normally, your router has an DHCP server built-in. However, there may be reasons to run a separate DHCP server, for example, if you write an entire network boot server (like the author did).
GitHub - gofeuer/l402: HTTP 402 Library for Lightning Payments
With the gofeuer
middleware, end users can pay for access keys via Bitcoin's Lightning network.
Completely unrelated to Go
Why aren't we all serverless yet?
Serverless architechtures have so many advantages; why is adoption so slow? Galo Navarro doesn't consider this a technical problem but rather an organizatorial one.
Seeing Software: Why we need to be choosers rather than users
Do software tools work for you, or do you work for the tools? Tara McMullin observes that standardized software influences work processes and communication, often leading users to unconsciously adapt their behavior to fit the tool rather than their needs.

Happy coding! ʕ◔ϖ◔ʔ
Questions or feedback? Drop me a line. I'd love to hear from you.
Best from Munich, Christoph
Not a subscriber yet?
If you read this newsletter issue online, or if someone forwarded the newsletter to you, subscribe for regular updates to get every new issue earlier than the online version, and more reliable than an occasional forwarding.
Find the subscription form at the end of this page.
How I can help
If you're looking for more useful content around Go, here are some ways I can help you become a better Gopher (or a Gopher at all):
On AppliedGo.net, I blog about Go projects, algorithms and data structures in Go, and other fun stuff.
Or visit the AppliedGo.com blog and learn about language specifics, Go updates, and programming-related stuff.
My AppliedGo YouTube channel hosts quick tip and crash course videos that help you get more productive and creative with Go.
Enroll in my Go course for developers that stands out for its intense use of animated graphics for explaining abstract concepts in an intuitive way. Numerous short and concise lectures allow you to schedule your learning flow as you like.
Christoph Berger IT Products and Services
Dachauer Straße 29
Bergkirchen
Germany