ProgrammingGo Developer

Describe the features of working with optional parameters and default values in Go, and how to implement flexible function interfaces with minimal rigidity.

Pass interviews with Hintsage AI assistant

Answer.

Go fundamentally does not support optional parameters and default values for function arguments — each function only accepts the set of arguments specified in its signature. This design decision is related to the overall simplicity of the model and predictability of the code.

Background

In other languages, such as Python or C++, optional/default parameters allow for flexible function behavior. In Go, this has been sacrificed for readability and clarity.

Problem

When it is necessary to make an API flexible, it is not possible to simply set default values — all parameters must either be explicitly passed or workaround patterns must be used. This complicates maintaining a large number of options and may lead to an increase in the number of overloaded functions.

Solution

In Go, two approaches are used for such flexibility:

  1. Parameter structure — a structure is created with a set of option fields that can be passed into the function. Inside the structure, default values can be explicitly defined.
  2. Variadic functions (functional options pattern) — a pattern that involves passing configuration functions that modify the object's configuration.

Example of the structure approach:

type QueryOptions struct { Limit int Offset int } func QueryDB(opts QueryOptions) { if opts.Limit == 0 { opts.Limit = 10 // default } // ... } QueryDB(QueryOptions{Limit: 100})

Or through functional options:

type Config struct { Timeout int } type Option func(*Config) func WithTimeout(t int) Option { return func(cfg *Config) { cfg.Timeout = t } } func Do(opts ...Option) { cfg := Config{Timeout: 5} // default for _, o := range opts { o(&cfg) } // ... } Do(WithTimeout(10)) // call with option Do() // call with default

Key features:

  • No optional/default parameters at the language level
  • Flexibility is achieved either through structures or functional patterns
  • Everything is explicit, without magic — it is always clear what and how is being passed

Tricky questions.

Can you set a default value when declaring a function, for example func F(a int = 10)?

No, such a declaration is not possible in Go — only a strict list of required parameters is allowed.

What happens if a function is declared with a slice of type ...interface{} and it is passed 0 arguments?

The slice will have a length of 0 (nil), and the function will receive an empty slice.

Example code:

func PrintAll(args ...interface{}) { fmt.Println(len(args)) // 0 if no parameters are passed } PrintAll() // ok

Is it possible to overload functions by the number or type of parameters in Go?

No, function overloading in Go is not supported — duplicate function names with different signatures are not allowed.

Common mistakes and anti-patterns

  • Attempt to implement overloading through variadic interfaces ( ...interface{} ), performing complex type checks manually
  • Overly expanding the API to dozens of parameters — this complicates maintenance
  • Hardcoding values inside functions without the ability to configure them

Real-life example

Negative case

An API function has dozens of parameters, many of them of the same type, causing mistakes due to confusing order:

Pros:

  • Everything is explicitly defined

Cons:

  • Errors due to unclear arguments
  • Uncertainty about default values

Positive case

A parameter structure or functional options is used, parameters have explicit names:

Pros:

  • Flexible and extensible signature
  • Support for defaults without ambiguity

Cons:

  • Need to maintain additional "wrapper" (structures, option functions)