Variable parameter functions in Swift

  • 2020-05-06 11:43:12
  • OfStack

Variable-argument functions are functions that take any number of arguments. The most familiar is probably NSString's -stringWithFormat: method. In Objective-C, we use this method to generate strings written like this:


NSString *name = @"Tom";
NSDate *date = [NSDate date];
NSString *string = [NSString stringWithFormat:
                @"Hello %@. Date: %@", name, date];

The parameters in this method can be changed arbitrarily. The first item of the parameter is the string that needs to be formatted. We won't go into the details of the variable-parameter functions in Objective-C (this is an Swift book, after all), but I believe that most readers with a few years of experience with Objective-C will have a hard time writing a function that accepts variable-parameters without looking up the material.

But this has been simplified as never before in Swift. Now, to write a function that takes a variable argument, you simply declare the argument by adding... That's it. For example, the following declaration is an Int summation function that accepts variable parameters:


func sum(input: Int...) -> Int {
    //...
}

The input input in the body of the function will be used as an array [Int]. Let's complete the above method. Of course you can use the traditional for... in does the summation, but here we've chosen a way to look more Swift:

func sum(input: Int...) -> Int {
    return input.reduce(0, combine: +)
} println(sum(1,2,3,4,5))
// Output: 15

The important thing to note when using a mutable parameter is that a mutable parameter can only be used as the last parameter in a method, and you cannot declare a mutable parameter and then declare other parameters. This is easy to understand because the compiler will not know where the input arguments should be truncated. In addition, there can be no more than one set of mutable parameters in a method.

One of the more annoying limitations is that mutable parameters must all be of the same type, so we need to be flexible when we want to pass in multiple types of parameters at the same time. For example, the -stringWithFormat: method was mentioned at the beginning. The first element of the variable-parameter list is the string waiting to be formatted, which in Swift corresponds to an String type, and the remaining arguments should be of any type corresponding to the formatting standard. One solution is to use Any as the argument type and then do special treatment to the first element of the received array. However, because Swift provides an external label that USES an underscore _ as an argument, it is no longer necessary to add the argument name to the call. We can take advantage of this feature by declaring the method to specify that the first argument is a string, followed by an anonymous argument list, so that when we write it "as if" all the arguments are in the same argument list, it looks much better. For example, Swift's NSString formatted declaration is handled like this:


extension NSString {
    convenience init(format: NSString, _ args: CVarArgType...)
    //...
}

When called, it is almost the same as when Objective-C, which is very convenient:

let name = "Tom"
let date = NSDate()
let string = NSString(format: "Hello %@. Date: %@", name, date)


Related articles: