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.
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
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)
}You should see three lines with defaults filled in where empty strings were passed.
Variadic optional arguments
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)
}Only the first optional string is used; extra arguments are ignored here by design.
Struct parameters and field defaults
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{"", ""}))
}Prefer plain Go fields and explicit defaulting when you can; tags plus reflect are optional sugar.
Map of named options
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}))
}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.

