Golang How to accept an arbitrary number of arguments

eye-catch Golang

There are some cases where we can’t specify the number of parameters for a function. How can we define such a function in Golang?

Sponsored links

Variadic function declaration

It’s easy to do it in Go. Prepend three dots before the data type.

func arbitraryNumbers(args ...int) {
    fmt.Println("--- arbitraryNumbers ---")
    fmt.Printf("0: %d, 1: %d\n", args[0], args[1])
    for index, arg := range args {
        fmt.Printf("%d: %d, ", index, arg)
    }
    fmt.Println()
}


func arbitraryStrings(args ...string) {
    fmt.Println("--- arbitraryStrings ---")
    fmt.Printf("0: %s, 1: %s\n", args[0], args[1])
    for index, arg := range args {
        fmt.Printf("%d: %s, ", index, arg)
    }
    fmt.Println()
}

The parameters are handled as an array so that we can read the value with an index.

The function can be called in the following way.

arbitraryNumbers(22, 77, 44, 57, 92, 23)
// --- arbitraryNumbers ---
// 0: 22, 1: 77
// 0: 22, 1: 77, 2: 44, 3: 57, 4: 92, 5: 23, 
arr := []int{22, 77, 44, 57, 92, 23}
arbitraryNumbers(arr...)
// --- arbitraryNumbers ---
// 0: 22, 1: 77
// 0: 22, 1: 77, 2: 44, 3: 57, 4: 92, 5: 23, 
arbitraryStrings("Hello", "Wor", "ld", "!!!")
// --- arbitraryStrings ---
// 0: Hello, 1: Wor
// 0: Hello, 1: Wor, 2: ld, 3: !!!, 

We can add as many parameters as we want. If the target variable we want to pass is an array/slice, add the three dots after the variable. It expands the array. So the result is the same.

Sponsored links

How to pass multipe data types to a function

If we want to pass both int and string to the function, we can use any. It is an alias as interface{}. It can be used from 1.18.

func arbitraryAny(args ...any) {
    fmt.Println("--- arbitraryAny ---")
    fmt.Printf("0: %v, 1: %v\n", args[0], args[1])
    for index, arg := range args {
        fmt.Printf("%d: %v, ", index, arg)
    }
    fmt.Println()
}

arbitraryAny("Hello", 123, "Wor", 987, "ld", 888, "!!!")
// --- arbitraryAny ---
// 0: Hello, 1: 123
// 0: Hello, 1: 123, 2: Wor, 3: 987, 4: ld, builtin5: 888, 6: !!!, 

Variadic function accepts struct type as well

It might accept a struct type. We can handle it in the same way as built-in types.

func arbitraryArgs(args ...any) {
    fmt.Println("--- arbitraryArgs ---")
    for index, val := range args {
        fmt.Printf("%d: ", index)

        switch v := val.(type) {
        case string:
            fmt.Println("String ", v)
        case int:
            fmt.Println("Int ", v)
        case float64:
            fmt.Println("Float64 ", v)
        case unknownObj1:
            fmt.Println("Special ", v)
        default:
            fmt.Println("Unknown data type: ", reflect.TypeOf(v))
        }
    }
}

arbitraryArgs(12, "string-value", []int{1, 2, 3}, 55, obj1, obj2)
// --- arbitraryArgs ---
// 0: Int  12
// 1: String  string-value
// 2: Unknown data type:  []int
// 3: Int  55
// 4: Special  {Yuto Hello World!}
// 5: Unknown data type:  utils.unknownObj2

If the value is a struct, we can access the property.

Check the following post too if you need to know any and interface{}.

Golang How to get value from any/interface
If a function has a parameter that is any or interface{}, it's not possible to access a property by a dot chain. How can we read a value in this case?

Comments

Copied title and URL