Mastering Go’s container/ring: Build and Optimize Circular Linked Lists
This article explains Go's container/ring package, detailing its Ring type, core methods, performance characteristics, practical code examples, and typical use cases such as schedulers and resource pools for efficient circular data handling.
Introduction
The Go standard library includes the container/ring package, which implements a circular linked list—a data structure where the last element points back to the first, enabling seamless cyclic traversal useful for resource pools, round‑robin scheduling, and similar scenarios.
Basic Structure
The package defines a Ring type:
type Ring struct {
next, prev *Ring
Value interface{} // stored data
}Each Ring node holds pointers to the next and previous nodes; a single‑element ring points to itself.
Main Functions and Methods
New(n int) *Ring– creates a ring with n elements. Next() *Ring – returns the next node. Prev() *Ring – returns the previous node. Move(n int) *Ring – moves forward or backward n positions. Link(s *Ring) *Ring – inserts another ring after the current node. Unlink(n int) *Ring – removes a sub‑ring of n nodes starting from the current node. Do(f func(interface{})) – applies a function to every element in the ring.
Usage Example
The following program demonstrates creating, initializing, printing, and linking rings:
package main
import (
"container/ring"
"fmt"
)
func main() {
// Create a ring with 3 elements
r := ring.New(3)
// Initialize values
n := r.Len()
for i := 0; i < n; i++ {
r.Value = i
r = r.Next()
}
// Print original ring
r.Do(func(p interface{}) { fmt.Println(p) })
// Create another ring with 2 elements
s := ring.New(2)
s.Value = 10
s = s.Next()
s.Value = 20
s.Do(func(p interface{}) { fmt.Println(p) })
// Link the second ring after the first
r.Link(s)
// Print the combined ring
r.Do(func(p interface{}) { fmt.Println(p) })
}Running this code prints the values of the original ring, the second ring, and then the combined ring after linking.
Performance Analysis
Operations on a circular linked list are O(1) because they involve only pointer updates. However, random access is slower than array or slice indexing, as it requires traversal from the start of the ring.
Typical Application Scenarios
Circular linked lists excel in contexts that need periodic or cyclic access, such as round‑robin schedulers, resource‑pool management, and buffered channels where elements are frequently inserted and removed.
Conclusion
The container/ring package provides a robust implementation of circular linked lists, enabling developers to manage cyclic data efficiently, improve performance in suitable workloads, and simplify resource‑rotation logic.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Ops Development & AI Practice
DevSecOps engineer sharing experiences and insights on AI, Web3, and Claude code development. Aims to help solve technical challenges, improve development efficiency, and grow through community interaction. Feel free to comment and discuss.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
