Function/Method Overloading means that that the same function/method name can be used with a different number and types of parameters
See this post for difference between function and method in Go – https://vikasboss.github.io/difference-between-method-function-go
Eg.
func X()
func X(name string)
func X(name, address string)
func X(name string, age int)
Go doesn’t support method/function overloading. See this faq for the reason https://golang.org/doc/faq#overloading
According to the above faq things are simpler without it.
We can workaround Method/Function overloading in GO using
- Variadic Function – A Variadic Function is a function that accepts a variable number of arguments
 - Empty Interface – It is an interface without any methods.
 
There are two cases for Method/Function Overloading
1.Different number of parameters but of the same type:
Above case can easily be handled using variadic functions. Notice in below code the parameters are of one type i.e. int.
package main
import "fmt"
func main() {
    fmt.Println(add(1, 2))
    fmt.Println(add(1, 2, 3))
    fmt.Println(add(1, 2, 3, 4))
}
func add(numbers ...int) int {
    sum := 0
    for _, num := range numbers {
        sum += num
    }
    return sum
Output:
3
6
10
2.Different number of parameters and of different types
This case can be handled using both variadic function and empty interface
package main
import "fmt"
func main() {
    handle(1, "abc")
    handle("abc", "xyz", 3)
    handle(1, 2, 3, 4)
}
func handle(params ...interface{}) {
    fmt.Println("Handle func called with parameters:")
    for _, param := range params {
        fmt.Printf("%v\n", param)
    }
}
Output:
Handle func called with parameters:
1
abc
Handle func called with parameters:
abc
xyz
3
Handle func called with parameters:
1
2
3
4
We can also use a switch case to get the exact parameters and use them accordingly. See the below example.
package main
import "fmt"
type person struct {
    name   string
    gender string
    age    int
}
func main() {
    err := addPerson("Tina", "Female", 20)
    if err != nil {
        fmt.Println("PersonAdd Error: " + err.Error())
    }
    
    err = addPerson("John", "Male")
    if err != nil {
        fmt.Println("PersonAdd Error: " + err.Error())
    }
     
    err = addPerson("Wick", 2, 3)
    if err != nil {
        fmt.Println("PersonAdd Error: " + err.Error())
    }
}
func addPerson(args ...interface{}) error {
    if len(args) > 3 {
        return fmt.Errorf("Wront number of arguments passed")
    }
    p := &person{}
    //0 is name
    //1 is gender
    //2 is age
    for i, arg := range args {
        switch i {
        case 0: // name
            name, ok := arg.(string)
            if !ok {
                return fmt.Errorf("Name is not passed as string")
            }
            p.name = name
        case 1:
            gender, ok := arg.(string)
            if !ok {
                return fmt.Errorf("Gender is not passed as string")
            }
            p.gender = gender
        case 2:
            age, ok := arg.(int)
            if !ok {
                return fmt.Errorf("Age is not passed as int")
            }
            p.age = age
        default:
            return fmt.Errorf("Wrong parametes passed")
        }
    }
    fmt.Printf("Person struct is %+v\n", p)
    return nil
}
Note: Wherever the arg is not passed it is substituted as default.
Output:
Person struct is &{name:Tina gender:Female age:20}
Person struct is &{name:John gender:Male age:0}
PersonAdd Error: Gender is not passed as string