About this channel
In this channel I will publish useful libraries, tips, quizzes and other information for Go developers.
My GitHub: https://github.com/ankddev
Channel link: https://t.me/golang_tips
My other channels:
- Rust::Tips - @rust_code_tips - about Rust language
Official Go Discord server: https://discord.com/invite/golang
Hashtags:
#tip - useful tip about language or it's tools
#code - code example
#program - project, wrote on Go
#library - useful library
#resource - useful resource about language
#idiomatic - idiomatic code and patterns
#book - book about Go or it's tools/projects
#fact - interesting or fun fact about Go
#goroutins - related to goroutins
#errors - error handling
#advanced - advanced topics
#project and #showcase - projects written in Go
#news - Go-related news
...and some other hashtags about specific topic!
In this channel I will publish useful libraries, tips, quizzes and other information for Go developers.
My GitHub: https://github.com/ankddev
Channel link: https://t.me/golang_tips
My other channels:
- Rust::Tips - @rust_code_tips - about Rust language
Official Go Discord server: https://discord.com/invite/golang
Hashtags:
#tip - useful tip about language or it's tools
#code - code example
#program - project, wrote on Go
#library - useful library
#resource - useful resource about language
#idiomatic - idiomatic code and patterns
#book - book about Go or it's tools/projects
#fact - interesting or fun fact about Go
#goroutins - related to goroutins
#errors - error handling
#advanced - advanced topics
#project and #showcase - projects written in Go
#news - Go-related news
...and some other hashtags about specific topic!
Use
Use
#tip #sync
@golang_tips
sync.Once
for Lazy InitializationUse
sync.Once
to ensure a function runs only once, even in concurrent scenarios. It's perfect for lazy initialization of shared resources.var once sync.Once
func initResource() {
fmt.Println("Initialized")
}
once.Do(initResource)
#tip #sync
@golang_tips
Use
Combine
#goroutins #tip
@golang_tips
time.After
for TimeoutsCombine
select
with time.After to handle timeouts in goroutines effectively.select {
case <-ch:
case <-time.After(time.Second):
fmt.Println("Timeout")
}
#goroutins #tip
@golang_tips
Use
Use the
#tip #code
@golang_tips
embed
for Static AssetsUse the
embed
package to 📦 include static assets like HTML or CSS directly in your 📎 binary.//go:embed index.html
var content embed.FS
#tip #code
@golang_tips
Use
🛠 Adjust
#code #tip
@golang_tips
runtime.GOMAXPROCS
for CPU Control🛠 Adjust
GOMAXPROCS
to control the number of OS threads used by Go programs.runtime.GOMAXPROCS(4)
#code #tip
@golang_tips
Handle structured errors with
Use
#tip #code #errors
@golang_tips
errors.As
Use
errors.As
to extract specific error types from a chain for granular error handling.type NotFoundError struct{ Msg string }
func (e *NotFoundError) Error() string { return e.Msg }
err := fmt.Errorf("wrapped: %w", &NotFoundError{Msg: "User not found"})
var target *NotFoundError
if errors.As(err, &target) {
fmt.Println("Found:", target.Msg) // Output: Found: User not found
}
#tip #code #errors
@golang_tips
Propagate Context deadlines for cancellable workflows
Use
#tip #code
@golang_tips
Use
context.WithTimeout
to enforce deadlines in distributed systems or long-running operations.ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
defer cancel()
select {
case <-time.After(1 * time.Second):
fmt.Println("Task completed")
case <-ctx.Done():
fmt.Println("Deadline exceeded:", ctx.Err()) // Output: Deadline exceeded
}
#tip #code
@golang_tips
👍1
Advanced Custom Allocators with
The standard memory allocation in Go is efficient for most cases, but when working with high-performance systems, you might need a custom allocator. Using
#advanced #tip
@golang_tips
sync.Pool
and Memory ReuseThe standard memory allocation in Go is efficient for most cases, but when working with high-performance systems, you might need a custom allocator. Using
sync.Pool
intelligently can reduce GC pressure by reusing objects. Design your pools to handle not just homogeneous objects, but to recycle complex structures. This tip covers how to implement pooling strategies that go beyond common examples, tailoring object reuse for high-frequency, low-latency tasks.package main
import (
"fmt"
"sync"
)
type Buffer struct {
data []byte
}
var bufferPool = sync.Pool{
New: func() interface{} { return &Buffer{data: make([]byte, 1024)} },
}
func processData() {
buf := bufferPool.Get().(*Buffer)
// simulate usage
buf.data[0] = 42
fmt.Println("Buffer first byte:", buf.data[0])
// Reset state if needed before putting back
bufferPool.Put(buf)
}
func main() {
processData()
}
#advanced #tip
@golang_tips
Complex Reflection Techniques for Dynamic Type Manipulation
Go’s reflect package provides powerful tools to inspect and manipulate types at runtime. This tip explores advanced patterns where you modify unexported fields or dynamically instantiate types using reflection. By combining deep type introspection with careful error checking, you can implement frameworks that automatically map data or perform dependency injection—all while navigating Go’s type system and ensuring runtime safety.
#tip #advanced
@golang_tips
Go’s reflect package provides powerful tools to inspect and manipulate types at runtime. This tip explores advanced patterns where you modify unexported fields or dynamically instantiate types using reflection. By combining deep type introspection with careful error checking, you can implement frameworks that automatically map data or perform dependency injection—all while navigating Go’s type system and ensuring runtime safety.
package main
import (
"fmt"
"reflect"
)
type secret struct {
value int
}
func main() {
s := secret{value: 10}
v := reflect.ValueOf(&s).Elem()
field := v.FieldByName("value")
if field.CanSet() {
field.SetInt(42)
}
fmt.Printf("Modified secret: %+v\n", s)
}
#tip #advanced
@golang_tips
❤1
Check that Interface value is equal to nil
If interface contains
prints
To correctly check if interface is equal to nil, you can write function, similar to
This function will work as expected.
#tip #example
@golang_tips
If interface contains
nil
, it can be not equal nil, e.g.func main() {
var x interface{}
var y *int = nil
x = y
if x != nil {
fmt.Println("x != nil") // <-- actual
} else {
fmt.Println("x == nil")
}
fmt.Println(x) } // x != nil // <nil>
prints
x != nil
<nil>
To correctly check if interface is equal to nil, you can write function, similar to
func IsNil(x interface{}) bool {
if x == nil {
return true
}
return reflect.ValueOf(x).IsNil()
}
This function will work as expected.
#tip #example
@golang_tips
new
vs make
Both
make()
and new()
are used for memory allocation. But make()
returns initialized type value, while new()
returns nil-pointer to type.a := new(chan int) // a has *chan int type
b := make(chan int) // b has chan int type
#tip #example
@golang_tips