Zum Hauptinhalt springen
tsecurity.de LIVE
Echtzeit-Radar & Feeds
Alle RSS Feeds
👥 Community & Social
Sichere ProgrammierungBreeze TTS 2 vs ElevenLabs: Open Source TTS Verdict(23.09.2026 um 05:44 Uhr)
Sichere ProgrammierungAgentic AI vs Generative AI: The 2026 Verdict(23.09.2026 um 05:44 Uhr)
Sichere ProgrammierungI made my agent prove every quote against the source document(23.09.2026 um 05:45 Uhr)
Sichere Programmierung8mb.video Alternative: Skip the Line, Skip the Upsell(23.09.2026 um 05:47 Uhr)
Sichere ProgrammierungBuilding a GTA 6 JSON API for entities and current status(23.09.2026 um 05:52 Uhr)
Sichere ProgrammierungEvery filter needs a documented exception(23.09.2026 um 06:01 Uhr)
Sichere ProgrammierungBreeze TTS 2 vs ElevenLabs: Open Source TTS Verdict(23.09.2026 um 05:44 Uhr)
Sichere ProgrammierungAgentic AI vs Generative AI: The 2026 Verdict(23.09.2026 um 05:44 Uhr)
Sichere ProgrammierungI made my agent prove every quote against the source document(23.09.2026 um 05:45 Uhr)
Sichere Programmierung8mb.video Alternative: Skip the Line, Skip the Upsell(23.09.2026 um 05:47 Uhr)
Sichere ProgrammierungBuilding a GTA 6 JSON API for entities and current status(23.09.2026 um 05:52 Uhr)
Sichere ProgrammierungEvery filter needs a documented exception(23.09.2026 um 06:01 Uhr)
Intelligence View
⚡ tsecurity.de Intelligence

Go Generics: When to Use Them, When to Avoid Them

I had three repositories that looked identical. UserRepository, ProductRepository, OrderRepository: same structure, same FindByID, same List, same pagination logic. The only difference was the return type. Three copies of the same code.…

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!

I had three repositories that looked identical. UserRepository, ProductRepository, OrderRepository: same structure, same FindByID, same List, same pagination logic. The only difference was the return type. Three copies of the same code. When Go 1.18 shipped with generics, I wanted to merge them all. What happened next taught me when generics are a good idea — and when they make the problem worse.






What generics actually do



Generics let you write code parameterized by types. Where before you had to either duplicate code for each type or use interface{} with runtime type assertions, you can now write a single implementation that works for multiple types — with compile-time checking.




// Before Go 1.18: duplication or interface{}
func ContainsInt(slice []int, val int) bool {
for _, v := range slice { if v == val { return true } }
return false
}
func ContainsString(slice []string, val string) bool {
for _, v := range slice { if v == val { return true } }
return false
}

// With generics: one implementation
func Contains[T comparable](slice []T, val T) bool {
for _, v := range slice {
if v == val {
return true
}
}
return false
}






T comparable is a constraint: T can be any type that supports ==. The compiler verifies that passed types satisfy the constraint — no runtime surprises.






Patterns where generics shine






1. Utility functions on slices and maps



This is the cleanest use case. Generic operations on collections, with no business logic:




func Filter[T any](slice []T, predicate func(T) bool) []T {
result := make([]T, 0, len(slice))
for _, v := range slice {
if predicate(v) {
result = append(result, v)
}
}
return result
}

func Map[T, U any](slice []T, transform func(T) U) []U {
result := make([]U, len(slice))
for i, v := range slice {
result[i] = transform(v)
}
return result
}

func Keys[K comparable, V any](m map[K]V) []K {
keys := make([]K, 0, len(m))
for k := range m {
keys = append(keys, k)
}
return keys
}






At the call site, it's readable and idiomatic:




activeUsers := Filter(users, func(u User) bool { return u.Active })
emails := Map(users, func(u User) string { return u.Email })
categoryIDs := Keys(categoryMap)









2. Typed data structures



A thread-safe cache, a queue, an optional value — structures you reuse everywhere but want typed:




type Cache[K comparable, V any] struct {
mu sync.RWMutex
items map[K]cacheEntry[V]
ttl time.Duration
}

type cacheEntry[V any] struct {
value V
expires time.Time
}

func NewCache[K comparable, V any](ttl time.Duration) *Cache[K, V] {
return &Cache[K, V]{
items: make(map[K]cacheEntry[V]),
ttl: ttl,
}
}

func (c *Cache[K, V]) Set(key K, value V) {
c.mu.Lock()
defer c.mu.Unlock()
c.items[key] = cacheEntry[V]{value: value, expires: time.Now().Add(c.ttl)}
}

func (c *Cache[K, V]) Get(key K) (V, bool) {
c.mu.RLock()
defer c.mu.RUnlock()
entry, ok := c.items[key]
if !ok || time.Now().After(entry.expires) {
var zero V
return zero, false
}
return entry.value, true
}






Without generics, this cache returns interface{} and forces a type assertion on every call. With generics, the type is known at compile time:




userCache := NewCache[int, User](5 * time.Minute)
userCache.Set(42, User{Name: "Alice"})
user, ok := userCache.Get(42) // user is a User, not an interface{}









3. Result and Option types



A common pattern to avoid null values or implicit boolean returns:




type Optional[T any] struct {
value T
present bool
}

func Some[T any](v T) Optional[T] { return Optional[T]{value: v, present: true} }
func None[T any]() Optional[T] { return Optional[T]{} }

func (o Optional[T]) Unwrap() (T, bool) { return o.value, o.present }
func (o Optional[T]) OrDefault(def T) T {
if o.present { return o.value }
return def
}









When generics make everything worse






The generic repository trap



Back to my three repositories. The idea seemed good:




type Repository[T any] struct {
db *sql.DB
table string
scan func(*sql.Rows) (T, error)
}

func (r *Repository[T]) FindByID(ctx context.Context, id int) (T, error) {
rows, err := r.db.QueryContext(ctx, "SELECT * FROM "+r.table+" WHERE id = $1", id)
// ...
return r.scan(rows)
}

func (r *Repository[T]) List(ctx context.Context) ([]T, error) {
// ...
}






In practice, it broke immediately. UserRepository needs FindByEmail. ProductRepository needs FindByCategory. OrderRepository needs FindByCustomerWithItems that does a join. The shared part — FindByID and List — represents 15% of the total code. The rest is specific. The generic factors out the 15%, complicates the 85%.




// What you end up writing anyway
type UserRepository struct {
base *Repository[User] // the generic part
db *sql.DB // for specific queries
}

// The complexity just moved somewhere else









Overly complex constraints



When generic constraints start looking like this, it's a signal:




// ❌ Too complex — use an interface instead
type Processable[T Entity, R Result, E interface{ error }] interface {
Process(context.Context, T) (R, E)
Validate(T) E
Rollback(context.Context, T) E
}

// ✅ A simple interface does the same job
type Processor interface {
Process(ctx context.Context, input any) (any, error)
}






If your generic constraint needs itself to be defined, or involves more than one type parameter with relationships between them, ordinary interfaces are almost always more readable.






When methods differ by type



Generics don't let you specialize behavior per type at runtime. If the logic differs between int and string, generics don't help — you need interfaces or two distinct functions.






The practical decision rule



Situation



Solution



Same algorithm, different types, identical logic



✅ Generics



Reusable data structure (cache, queue, optional)



✅ Generics



Behavior varies by type



✅ Interfaces



Factoring business logic that differs 85% of the time



❌ Avoid generics



Constraint with more than 2 type params



❌ Probably an interface



Need reflection or type switch



❌ Generics can't help



The key question: is the logic identical for all types, or just the structure? If it's the logic: generics. If it's the behavior: interfaces. If it's both: compose them.






Conclusion



Go generics are a measured addition to a language that already valued simplicity. They don't replace interfaces — they fill a specific blind spot: algorithms and data structures that work identically for any type.



What took me time to internalize: generics are a tool for eliminating structural code duplication, not for factoring business logic. As soon as logic starts diverging by type, you leave generics territory and enter interfaces territory — which, combined with functional options and solid DI, covers the vast majority of real-world Go architecture cases.

Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Go Generics: When to Use Them, When to Avoid Them

Thematisch verwandte Begriffe: Generics, When, Them, Avoid · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-18163 | IBM Financial Transaction Manager (FTM) for RedHat OpenShift could allow…
Advisory →
TTS Reader • tsecurity.de Voice
tsecurity.de Icon
tsecurity.de App
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag
Themen-Radar & Intelligence Matrix
Echtzeit-Taxonomie nach Angriffsvektoren & Plattformen

tsecurity.de Live Threat Radar

🔴 LIVE RADAR
MONITORING
AKTIV
CVE-DATENBANK
LIVE
🔍
Community Radar & Live Chat
Sentinel Bot online • Live-Stream
Dein Cluster: Security Explorer
Match:
lädt…
Verbindung zum Community-Stream wird aufgebaut...
Bearbeitungsmodus — Senden überschreibt deine Nachricht
Community-Puls — was gerade passiert
lädt…
Aktivitäten deiner Analysten
lädt…
Neues Thema oder Eilmeldung einreichen

Reiche interessante Links, Zero-Days oder Debatten ein. Die Community entscheidet per Upvote über die Veröffentlichung.

Heiß diskutierte Einreichungen
🔖 Gespeicherte Artikel
📂 Keine gespeicherten Artikel vorhanden.
Zurück Ziehen Vor
Links: vorheriger Artikel Rechts: nächster Artikel unten: schließen
News NIS-2 Frühwarnung Tier-1 Intel ⏱️ 3 Min vor 10 Min
Artikeldaten werden geladen...

Zurück: vorheriger Vor: nächster
↗ Original-Quelle
Social Reaktionen Deine Reaktion zählt
Einstufung & Relevanz-Poll 0 Stimmen
In sozialen Netzwerken teilen 1-Klick