Understanding Optional Parameters in Golang

Golang does not support optional function parameters by design. This means you cannot set default values for parameters in Go.

However, there are some turnarounds or methods to pass optional parameters to a function in Go.

  1. Method 1: Using the variadic function
  2. Method 2: Using a struct with optional fields

Method 1: Using the variadic functions

You can pass the optional parameters to a function using a variadic function. A variadic function accepts a variable number of arguments of the same type.

You can define a variadic function by using an ellipsis (…) before the last parameter type in the function signature.

Syntax

func ExampleFunc(requiredArg string, optionalArgs ...string) {
  fmt.Println(requiredArg)
  for _, arg := range optionalArgs {
    fmt.Println(arg)
 }
}

Example 1

package main

import "fmt"

func sum(nums ...int) int {
  total := 0
  for _, num := range nums {
    total += num
  }
  return total
}

func main() {
  fmt.Println(sum(1, 2, 3))
  fmt.Println(sum(10, 20))
  fmt.Println(sum())
}

Output

6
30
0

Example 2

You can also pass an existing slice to a variadic function using an ellipsis after the slice name.

package main

import "fmt"

func sum(nums ...int) int {
  total := 0
  for _, num := range nums {
    total += num
  }
  return total
}

func main() {
  numbers := []int{1, 2, 3, 4, 5}
  fmt.Println(sum(numbers...))
}

Output

15

Method 2: Using a struct with optional fields

Another way to pass optional parameters to a function is to use a struct with optional fields as the argument type. This way, you can create a struct that contains all the possible parameters for the function and use pointers or empty values for the optional fields.

Syntax

type Options struct {
   OptionalArg1 string
   OptionalArg2 int
}

func ExampleFunc(requiredArg string, opts Options) {
  fmt.Println(requiredArg)
  if opts.OptionalArg1 != "" {
    fmt.Println(opts.OptionalArg1)
  }
  if opts.OptionalArg2 != 0 {
    fmt.Println(opts.OptionalArg2)
  }
}

Example

package main

import "fmt"

type User struct {
  Name string
  Email string
  Age *int // optional
  Phone *string // optional
}

func NewUser(params User) *User {
 
 // create a new user with the given parameters
 // if params.Age or params.Phone are nil, use default values
 
 user := &User{
   Name: params.Name,
   Email: params.Email,
   Age: params.Age,
   Phone: params.Phone,
 }

 if user.Age == nil {
   defaultAge := 18
   user.Age = &defaultAge
 }
 
 if user.Phone == nil {
   defaultPhone := "+1-800-123-4567"
   user.Phone = &defaultPhone
 }
 return user
}

func main() {
  user1 := NewUser(User{
    Name: "Krunal",
    Email: "krunal@example.com",
 })
  age := 30
  phone := "+1-234-567-8901"

  user2 := NewUser(User{
    Name: "Ankit",
    Email: "ankit@example.com",
    Age: &age, // creates a pointer to an existing int variable
    Phone: &phone, // creates a pointer to an existing string variable
 })

 fmt.Println(user1)
 fmt.Println(user2)
}

Output

&{Krunal krunal@example.com 0x1400001a0a8 0x14000010240}
&{Ankit ankit@example.com 0x1400001a0b0 0x14000010250}

This way, you can pass optional parameters to the function using a struct with optional fields. 

That’s it.

Leave a Comment