Default and optional parameters in Go (patterns, not language syntax)

Go has no default parameter values at compile time; use zero-value checks, variadic trailing arguments, a struct of fields, or a map[string]any with defaults applied in the function body.

Published

Updated

Read time 3 min read

Reviewed byDeepak Prasad

Default and optional parameters in Go (patterns, not language syntax)

Go does not let you assign default values in the function signature the way Python does. Callers always pass every positional argument, or you redesign the API: zero-value checks, variadic functions, a parameter struct, or a small map of named fields. The following patterns are idiomatic.

python
def name(firstname, lastname="Mark", standard="Fifth"):
    print(firstname, lastname, "studies in", standard, "Standard")

name("John")
name("John", "Gates", "Seventh")
name("John", "Gates")

Tested with Go 1.24 on Linux.


Zero-value defaults

go
package main

import "fmt"

func main() {
	fmt.Println(GetStudentInfo("", ""))
	fmt.Println(GetStudentInfo("Anna", ""))
	fmt.Println(GetStudentInfo("", "+145366"))
}

func GetStudentInfo(name, phone string) string {
	if name == "" {
		name = "default-name"
	}
	if phone == "" {
		phone = "default-phoneNumber"
	}
	return fmt.Sprintf("Name: %s, Phone number: %s", name, phone)
}
Output

You should see three lines with defaults filled in where empty strings were passed.


Variadic optional arguments

go
package main

import "fmt"

func main() {
	fmt.Println(GetStudentInfo2("Anna"))
	fmt.Println(GetStudentInfo2("Teddy", "+3688269"))
	fmt.Println(GetStudentInfo2("Adele", "+145366", "+58963144"))
}

func GetStudentInfo2(name string, phoneOptional ...string) string {
	phone := "default-phoneNumber"
	if len(phoneOptional) > 0 {
		phone = phoneOptional[0]
	}
	return fmt.Sprintf("Name: %s, Phone number: %s", name, phone)
}
Output

Only the first optional string is used; extra arguments are ignored here by design.


Struct parameters and field defaults

go
package main

import (
	"fmt"
	"reflect"
)

type Param struct {
	Name        string `default:"default-name"`
	PhoneNumber string `default:"default-phoneNumber"`
}

func GetStudentInfo3(prm Param) string {
	typ := reflect.TypeOf(prm)
	if prm.Name == "" {
		f, _ := typ.FieldByName("Name")
		prm.Name = f.Tag.Get("default")
	}
	if prm.PhoneNumber == "" {
		f, _ := typ.FieldByName("PhoneNumber")
		prm.PhoneNumber = f.Tag.Get("default")
	}
	return fmt.Sprintf("Name: %s, Phone number: %s", prm.Name, prm.PhoneNumber)
}

func main() {
	fmt.Println(GetStudentInfo3(Param{"Anna", ""}))
	fmt.Println(GetStudentInfo3(Param{"Teddy", "+3688269"}))
	fmt.Println(GetStudentInfo3(Param{"", ""}))
}
Output

Prefer plain Go fields and explicit defaulting when you can; tags plus reflect are optional sugar.


Map of named options

go
package main

import "fmt"

type varArgs map[string]any

func GetStudentInfo4(args varArgs) string {
	name := "default-name"
	if v, ok := args["Name"]; ok {
		name = v.(string)
	}
	age := 50
	if v, ok := args["Age"]; ok {
		age = v.(int)
	}
	return fmt.Sprintf("Name: %s, Age: %d", name, age)
}

func main() {
	fmt.Println(GetStudentInfo4(varArgs{}))
	fmt.Println(GetStudentInfo4(varArgs{"Name": "Harry Potter"}))
	fmt.Println(GetStudentInfo4(varArgs{"Name": "Lady Gaga", "Age": 40}))
}
Output

Use type switches instead of bare type assertions when keys might be missing or mistyped.


Summary

There is no golang default parameter keyword; defaults live in function bodies. Zero values, variadic suffix parameters, structs, and maps are all common. For public APIs, structs or functional options usually read clearer than many positional parameters with implicit defaults.


References


Frequently Asked Questions

1. Does Go support default arguments like Python?

No. You choose patterns: treat the zero value as default, add variadic optional parameters, pass a struct or map, or use a functional options pattern.

2. What is wrong with reflect and struct tags for defaults?

It works but adds runtime cost and indirection; prefer explicit fields or a small constructor for anything performance-sensitive or security-sensitive.

3. How do variadic parameters emulate optional strings?

Declare func f(name string, opts ...string) and read opts[0] when len(opts) > 0; see variadic functions in Go for details.

4. How do I document which parameters are optional?

Use clear names, a struct type, or an options type so call sites read like named configuration instead of positional magic.

5. Where are function parameters covered?

See function parameters in Go for passing by value versus pointer.
Tuan Nguyen

Data Scientist

Proficient in Golang, Python, Java, MongoDB, Selenium, Spring Boot, Kubernetes, Scrapy, API development, Docker, Data Scraping, PrimeFaces, Linux, Data Structures, and Data Mining. With expertise …