Question
Is there a way to specify a default value for a function parameter in Go? I could not find anything in the documentation that confirms whether this is possible.
For example, I was trying something like this:
func SaySomething(i string = "Hello") string {
// ...
}
Is this supported in Go, and if not, what is the usual Go-style way to handle default values?
Short Answer
By the end of this page, you will understand that Go does not support default parameter values in function signatures. You will also learn the common Go patterns used instead, such as wrapper functions, zero-value checks, configuration structs, and variadic parameters where appropriate.
Concept
Go keeps function declarations simple and explicit. Unlike some languages, Go does not allow you to assign default values directly in a function signature.
So this is not valid Go:
func SaySomething(i string = "Hello") string {
return i
}
In Go, every declared parameter must be passed explicitly when calling the function, unless you design your API to support optional behavior in another way.
Why does this matter?
- Go favors clarity over magic.
- Function calls should be easy to read and understand.
- The language encourages simple, predictable patterns instead of many special syntax rules.
Because default arguments are not built into the language, Go developers typically use one of these approaches:
- Wrapper functions for common defaults
- Zero-value checks inside the function
- Configuration structs for many optional settings
- Variadic parameters in limited cases
These patterns are widely used in real Go code and are considered idiomatic.
Mental Model
Think of a Go function like a form that requires all listed fields to be filled in exactly as written.
In some languages, a form field can say, "If left blank, use Hello." Go does not do that in the function signature.
Instead, Go developers handle defaults in one of these ways:
- Create a shorter form that fills in the common values for you
- Check whether the caller gave an empty value and replace it
- Pass a settings object where missing fields use defaults
So the default is not attached to the parameter declaration itself. It is handled by your program logic.
Syntax and Examples
In Go, you must declare parameters without default assignments:
func SaySomething(message string) string {
return message
}
Pattern 1: Wrapper function
Use one function for the full behavior and another for the common default.
package main
import "fmt"
func SaySomething(message string) string {
return message
}
func SayHello() string {
return SaySomething("Hello")
}
func main() {
fmt.Println(SaySomething("Hi"))
fmt.Println(SayHello())
}
This is often the clearest approach when there is one common default.
Pattern 2: Zero-value check
If an empty string should mean "use the default," check it inside the function.
package main
{
message == {
message =
}
message
}
{
fmt.Println(SaySomething())
fmt.Println(SaySomething())
}
Step by Step Execution
Consider this example:
package main
import "fmt"
func SaySomething(message string) string {
if message == "" {
message = "Hello"
}
return message
}
func main() {
fmt.Println(SaySomething(""))
}
Step by step:
-
main()callsSaySomething(""). -
The
messageparameter receives the empty string. -
Inside
SaySomething, Go checks:if message == "" { -
The condition is true, so
messageis changed to"Hello". -
The function returns .
Real World Use Cases
Default-like behavior appears often in Go programs, even though the language has no default parameters.
Common examples
- CLI tools: if no output path is provided, use
./output.txt - HTTP clients: if no timeout is set, use a standard timeout
- Logging: if no log level is provided, use
info - Data processing: if no delimiter is passed, use a comma
- API request builders: if no page size is specified, use a default size
Example: file reader with a default path
func ReadFile(path string) string {
if path == "" {
path = "default.txt"
}
return "Reading: " + path
}
Example: app configuration
type Config struct {
Port int
}
func StartServer(cfg Config) int {
if cfg.Port == 0 {
cfg.Port = 8080
}
return cfg.Port
}
Real Codebase Usage
In real Go codebases, developers usually avoid trying to imitate another language's default-argument syntax. Instead, they use clear patterns that fit Go.
1. Wrapper functions for common cases
A public API may offer both a full function and a convenience function.
func ConnectWithTimeout(addr string, timeout int) error {
// connect logic
return nil
}
func Connect(addr string) error {
return ConnectWithTimeout(addr, 30)
}
This makes the default obvious and keeps calls readable.
2. Validation and default assignment at the start
Developers often normalize inputs early.
func CreateUser(name string) string {
if name == "" {
name = "Guest"
}
return name
}
This is similar to a guard clause: handle unusual or missing input first, then continue.
3. Config structs for scalable APIs
Common Mistakes
Mistake 1: Trying to assign a default in the parameter list
Broken code:
func SaySomething(message string = "Hello") string {
return message
}
Why it fails:
- Go syntax does not allow default parameter values.
Fix:
func SaySomething(message string) string {
if message == "" {
message = "Hello"
}
return message
}
Mistake 2: Assuming empty string always means "not provided"
Broken idea:
func SaveName(name string) string {
if name == "" {
name = "Anonymous"
}
return name
}
Problem:
- Sometimes an empty string is a valid, intentional value.
Comparisons
| Approach | How it works | Best when | Pros | Cons |
|---|---|---|---|---|
| Wrapper function | A second function supplies the common value | There is one clear default | Very readable, idiomatic | Can create extra small functions |
| Zero-value check | Replace "", 0, or other zero values inside the function | Zero value truly means “use default” | Simple and short | Can hide intentional zero-value input |
| Variadic parameter | Accept ...T and use first item if present | One optional value in a small API | Flexible | Less explicit, easier to misuse |
| Config struct | Pass a struct with fields, fill defaults inside | Many optional settings |
Cheat Sheet
// Not allowed in Go
func SaySomething(message string = "Hello") string // invalid
Valid ways to handle defaults
1. Wrapper function
func SaySomething(message string) string {
return message
}
func SayHello() string {
return SaySomething("Hello")
}
2. Zero-value check
func SaySomething(message string) string {
if message == "" {
message = "Hello"
}
return message
}
3. Variadic parameter
func {
message :=
(messages) > {
message = messages[]
}
message
}
FAQ
Can Go functions have default parameter values?
No. Go does not support default values in function signatures.
How do I simulate optional parameters in Go?
Common approaches are wrapper functions, zero-value checks, variadic parameters, and config structs.
What is the most idiomatic way to handle defaults in Go?
Usually a wrapper function for simple cases, or a config struct for multiple optional settings.
Can I overload functions in Go instead of using defaults?
No. Go does not support function overloading.
Is using an empty string as a default trigger a good idea?
Only if an empty string truly means “not provided” in your program. Otherwise, it can hide valid input.
Are variadic parameters a good replacement for default arguments?
Sometimes for very small cases, but they are usually less clear than wrapper functions or structs.
Why did Go leave out default arguments?
Go favors simple, explicit language features and avoids adding extra function-call rules that can reduce clarity.
Mini Project
Description
Build a small greeting utility that demonstrates several Go-style ways to handle default values without using default parameters in the function signature. This project is useful because greeting and message formatting are simple examples of a larger real-world pattern: providing sensible defaults while keeping APIs clear.
Goal
Create a Go program that prints greetings using a default message when no custom message is supplied.
Requirements
- Create a function that returns a greeting using a provided message.
- If the message is empty, use
Helloas the default. - Add a wrapper function that always uses the default greeting.
- Print at least one custom greeting and one default greeting.
- Keep the program valid, runnable Go code.
Keep learning
Related questions
Blank Identifier Imports in Go: What `_` Means in an Import Statement
Learn what `_` means in a Go import, why blank identifier imports run package init code, and when to use them safely.
Calling Functions Across Files in the Same Go Package
Learn how Go uses packages across multiple files, why functions may appear undefined, and how to organize code correctly.
Check if a Value Exists in a Slice in Go
Learn how to check whether a value exists in a slice in Go, and why Go has no Python-style `in` operator for arrays or slices.