Pointless
A Go linter that suggests using value types instead of pointers for small structs.
Install / Use
/learn @mickamy/PointlessREADME
pointless
A Go linter that suggests using value types instead of pointers for small structs.
The name is a pun: "pointer" + "less" = "pointless" (also meaning "unnecessary").
Installation
go install github.com/mickamy/pointless@latest
Usage
# Basic usage
pointless ./...
# Change threshold (default: 1024 bytes)
pointless -threshold 512 ./...
What It Detects
1. Function Return Types
// Warning: consider returning value instead of pointer
func GetUser() *User { ... }
// OK: may return nil
func FindUser(id int) *User {
if notFound {
return nil
}
return &user
}
// OK: struct is large (> 1024 bytes)
func GetData() *LargeData { ... }
2. Method Receivers
// Warning: consider using value receiver
func (u *User) FullName() string {
return u.FirstName + " " + u.LastName // read-only
}
// OK: mutates receiver
func (u *User) SetName(name string) {
u.Name = name
}
3. Pointer Slices
// Warning: consider using []User instead of []*User
func GetUsers() []*User { ... }
users := make([]*User, 100)
// OK: uses nil as element
if users[i] == nil { ... }
Not Checked: Function Arguments
// Too difficult to determine intent
func (r *UserRepo) Update(u *User) error
func Process(u *User) error
Suppressing Warnings
// nolint:pointless
func GetUser() *User { ... }
// pointless:ignore
func GetUser() *User { ... }
// nolint
func GetUser() *User { ... }
Configuration
Create .pointless.yaml or .pointless.yml in your project root:
threshold: 1024 # bytes
exclude:
- "*_test.go"
- "vendor/**"
CI Integration
# .github/workflows/lint.yaml
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '1.24'
- name: pointless
run: |
go install github.com/mickamy/pointless@latest
pointless ./...
Why Prefer Value Types?
Memory Layout
[]User (value slice):
┌────────┬────────┬────────┬────────┐
│ User 0 │ User 1 │ User 2 │ User 3 │ ← contiguous memory
└────────┴────────┴────────┴────────┘
[]*User (pointer slice):
┌────┬────┬────┬────┐
│ * │ * │ * │ * │ ← pointer array
└─┬──┴─┬──┴─┬──┴─┬──┘
│ │ │ │
▼ ▼ ▼ ▼
┌────┐┌────┐┌────┐┌────┐ ← scattered allocations
│User││User││User││User│
└────┘└────┘└────┘└────┘
Benefits of Value Types
- CPU cache efficiency - Contiguous memory improves spatial locality
- Fewer allocations - 1 allocation vs N+1 allocations
- Lower GC pressure - Fewer pointers to track
- Immutability - Prevents unintended mutations
Why 1024 Bytes as Default Threshold?
- Go goroutine stacks start at 2KB and grow automatically
- A struct with ~50 fields typically uses 400-800 bytes
- Contiguous memory copies are efficiently handled by CPU (SIMD-optimized memcpy)
- Pointer indirection can cause cache misses, which may be more expensive than copying
- Slice/map fields only copy the header, not the underlying data
License
Related Skills
node-connect
346.8kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
107.6kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
346.8kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
346.8kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
