Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to forward functions with variadic parameters?

Tags:

In Swift, how do you convert an Array to a Tuple?

The issue came up because I am trying to call a function that takes a variable number of arguments inside a function that takes a variable number of arguments.

// Function 1 func sumOf(numbers: Int...) -> Int {     var sum = 0     for number in numbers {         sum += number     }     return sum } // Example Usage sumOf(2, 5, 1)  // Function 2 func averageOf(numbers: Int...) -> Int {     return sumOf(numbers) / numbers.count } 

This averageOf implementation seemed reasonable to me, but it does not compile. It gives the following error when you try to call sumOf(numbers):

Could not find an overload for '__converstion' that accepts the supplied arguments 

Inside averageOf, numbers has the type Int[]. I believe sumOf is expecting a Tuple rather than an Array.

Thus, in Swift, how do you convert an Array to a Tuple?

like image 222
bearMountain Avatar asked Jun 04 '14 19:06

bearMountain


People also ask

What are variadic parameters in Python?

Variadic parameters (Variable Length argument) are Python's solution to that problem. A Variadic Parameter accepts arbitrary arguments and collects them into a data structure without raising an error for unmatched parameters numbers.

Why do we use variadic parameters in Swift?

A variadic parameter accepts zero or more values of a specified type. You use a variadic parameter to specify that the parameter can be passed a varying number of input values when the function is called.

Is printf variadic function?

Variadic functions are functions (e.g. printf) which take a variable number of arguments.


1 Answers

This has nothing to do with tuples. Anyway, it isn't possible to convert from an array to a tuple in the general case, as the arrays can have any length, and the arity of a tuple must be known at compile time.

However, you can solve your problem by providing overloads:

// This function does the actual work func sumOf(_ numbers: [Int]) -> Int {     return numbers.reduce(0, +) // functional style with reduce }  // This overload allows the variadic notation and // forwards its args to the function above func sumOf(_ numbers: Int...) -> Int {     return sumOf(numbers) }  sumOf(2, 5, 1)  func averageOf(_ numbers: Int...) -> Int {     // This calls the first function directly     return sumOf(numbers) / numbers.count }  averageOf(2, 5, 1) 

Maybe there is a better way (e.g., Scala uses a special type ascription to avoid needing the overload; you could write in Scala sumOf(numbers: _*) from within averageOf without defining two functions), but I haven't found it in the docs.

like image 85
Jean-Philippe Pellet Avatar answered Sep 19 '22 19:09

Jean-Philippe Pellet