How to Pass a Default Value to a Method in Go: 5 Real Solutions

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Why Go Doesn't Have Default Parameters (And That's a Good Thing)



Imagine: you're writing in Go and want to create a method with a parameter that can be omitted. Like in Python: def greet(name="Guest"). You reach for the keyboard, write:



func (u *User) Greet(message string = "Hello") string {    return message + ", " + u.Name}


And Go throws an error. The compiler blushes but doesn't let it through. Sound familiar? This question (the original on Stack Overflow has thousands of views) plagues every second Go beginner. The language developers deliberately refused default values. Why? Because Go is a language of explicitness. Code readability is more important than brevity. But this doesn't mean you can't simulate a default value in Go. There are at least 5 elegant ways. Let's break down each one.



Method 1: Overloading via Different Functions (Go-way)



The simplest and most "Go-idiomatic" approach is to simply create two functions. One with a parameter, one without.



type Config struct {    Timeout int}

func NewDefaultConfig() *Config { return &Config{Timeout: 30} // default value}

func NewConfig(timeout int) *Config { if timeout <= 0 { timeout = 30 // foolproofing } return &Config{Timeout: timeout}}


Pros: Extremely clear, readable in a second.
Cons: With 3-4 parameters, you'll end up with a function explosion.



Method 2: Struct with Constructor (Builder Pattern)



When there are many parameters (3+), the Builder pattern comes to the rescue. This is a standard idiom in Go for working with optional parameters.



type Server struct {    Host    string    Port    int    Timeout time.Duration    MaxConn int}

// Default valuesfunc NewServer() *Server { return &Server{ Host: "localhost", Port: 8080, Timeout: 30 * time.Second, MaxConn: 100, }}

// Setter methods return the object itselffunc (s *Server) WithHost(host string) *Server { s.Host = host return s}

func (s *Server) WithPort(port int) *Server { s.Port = port return s}

// Usageserver := NewServer(). WithPort(9090). WithTimeout(10 * time.Second)


This pattern is actively used in the Go standard library (e.g., http.Server). It solves the default parameters Go problem without hacks.



Method 3: Variadic Parameters (Unexpected Trick)



You can use variadic parameters (the ... notation). This is a non-obvious but working technique for a single optional parameter.



func Greet(name string, opts ...string) string {    greeting := "Hello" // default value    if len(opts) > 0 {        greeting = opts[0]    }    return greeting + ", " + name}

// Usagefmt.Println(Greet("Ivan")) // "Hello, Ivan"fmt.Println(Greet("Maria", "Greetings")) // "Greetings, Maria"


It works, but looks like a crutch. Use it only if you need a quick solution.



Method 4: Functional Options (Most Go-idiomatic)



This is the signature technique of Go developers. First popularized by Dave Cheney. It allows you to set a default value in Go for any number of parameters.



type Option func(*Client)

type Client struct { URL string Timeout time.Duration Retries int}

// Default valuesfunc defaultClient() *Client { return &Client{ URL: "https://api.example.com", Timeout: 10 * time.Second, Retries: 3, }}

// Optionsfunc WithURL(url string) Option { return func(c *Client) { c.URL = url }}

func WithTimeout(t time.Duration) Option { return func(c *Client) {

Blogs

Book Recommendations