# Go Optional Function Parameters with Variadic and Structs

> Simulate optional function parameters in Go using variadic functions for flexible argument counts and struct zero values for named defaults with examples

**URL:** https://sentry.io/answers/optional-functional-parameters-in-go/

---

## The Problem

You want to write functions with optional parameters in Go, but the language doesn't support this feature.

## The Solution

While Go doesn't support optional parameters, you can approximate them with [variadic functions](https://en.wikipedia.org/wiki/Variadic_function) or [zero values](https://go.dev/ref/spec#The_zero_value).

### Variadic Functions

In Go, functions can specify a type of parameter that contains zero or more values.

For example, the `sum()` function accepts any number of integer (`int`) parameters and adds them together:

```go
package main

import "log"

func sum(numbers ...int) int {
	result := 0
	for _, n := range numbers {
		result += n
	}

	return result
}

func main() {
	log.Println(sum())        // Prints "0".
	log.Println(sum(1))       // Prints "1".
	log.Println(sum(1, 2, 3)) // Prints "6".
}
```

Variadic functions must specify the variadic parameter as the final parameter. 

- For example, the following variadic function is valid:

  ```
  func sum(start int, numbers ...int) int
  ```

- Whereas the following variadic function is not:

  ```
  func sum(numbers ...int, start int) int
  ```

### Zero Values

You can simulate some of the functions of optional parameters by specifying a `struct` as the parameter of a function in Go. Functions with `struct` parameters have default zero-value arguments. The argument is assumed to be `0` when left empty for these functions.

```go
package main

import "log"

type operations struct {
	// initialValue will be 0 if not specified.
	initialValue int
	// So will add and subtract.
	add, subtract int
	// doubleResult will be false if not specified.
	doubleResult bool
}

func calculate(ops operations) int {
	result := ops.initialValue
	result += ops.add
	result -= ops.subtract

	if ops.doubleResult {
		result *= 2
	}

	return result
}

func main() {
	log.Println(calculate(operations{}))                                                         // Prints "0".
	log.Println(calculate(operations{initialValue: 1}))                                          // Prints "1".
	log.Println(calculate(operations{initialValue: 1, add: 5}))                                  // Prints "6".
	log.Println(calculate(operations{initialValue: 1, add: 5, subtract: 2, doubleResult: true})) // Prints "8".

	// Or, using unnamed fields:
	log.Println(calculate(operations{1, 5, 2, true})) // Prints "8".
}
```

While the potential default values are limited, this approach is useful for specific cases.

## Further Reading

- The [Variadic function](https://en.wikipedia.org/wiki/Variadic_function) Wikipedia article 
- [The zero value](https://go.dev/ref/spec#The_zero_value) section of The Go Programming Language Specification

---

*Source: [sentry.io/answers/optional-functional-parameters-in-go/](https://sentry.io/answers/optional-functional-parameters-in-go/)*
