Functions Revisited Again: Input Parameters - ADDITIONAL TOPICS - Understanding Swift Programming: Swift 2 (2015)

Understanding Swift Programming: Swift 2 (2015)

PART 3: ADDITIONAL TOPICS

22. Functions Revisited Again: Input Parameters

Earlier chapters introduced functions and methods and described their basic syntax (motivated by the syntax of Objective-C), that uses named parameters. (In Swift 2 named parameters are used in both functions and methods. In Swift 1 named parameters are only used in methods.)

Functions and methods also have many possible variations allowed for input parameters. The purpose of the present chapter is to describe these variations.

This chapter will cover five different possible variations for input parameters. They are:

1. The use of external parameter names, which are the default for both functions and methods in Swift 2.

2. Variable parameters. By default, input parameters are constants. By declaring them as variables, they can be modified within the function, although they are not available outside the function.

3. In-out parameters, which allow external variables to be passed by reference to the function, modified within it, and returned.

4. Default parameter values. Default values can be specified for input parameters within the input parameter parentheses.

5. Variadic parameters. A variable number of parameters is allowed for one type of the input parameters.

An example of the most basic form of a Swift function is shown below:

func addTwoNumbersWithFirst (first: Int, second: Int) -> Int {

var c = first + second

return c

}

var d = addTwoNumbersWithFirst(2, second: 5)

A function is allowed to have no parameters at all, but must still, in that case, have parentheses, even though they are empty. (This requirement is unlike that for the return arrow and type for the return value, which can both be omitted entirely if there is no return value.)

func functionNoInputsOrReturn() {

print("Hello")

}

var e = functionNoInputsOrReturn ()

Variations in External Parameter Names

The syntax for the example of a basic function presented above has two input parameters, and the input parameter syntax declares two constants, a and b to be parameters. These are local parameter names, and their purpose is to allow the parameters to be referenced within the body of the function.

func addTwoNumbers (a: Int, b: Int) -> Int {

var c = a + b

return c

}

In Swift 2, these local parameter names are used as the default external parameter names for calling functions and methods:

var d = addTwoNumbers(2, b: 5)

This doesn’t make a lot of sense from the viewpoint of the calling statement, however. We can fix this by changing the name of the function and adding an external parameter name for the second parameter:

func addTwoNumbersWithFirst (a: Int, second b: Int) -> Int {

var c = a + b

return c

}

which is called with:

var d = addTwoNumbersWithFirst(2, second: 5)

The local name for the second parameter is still b, but now there is an external name, second.

Note that the external parameter names don't mean anything within the body of the function.

It's possible to define an external name for the first parameter of a function or method, if you really want to:

func addTwoNumbers (first first: Int, second: Int) -> Int {

var c = first + second

return c

}

This is called with:

var d = addTwoNumbers (first: 2, second: 5)

In Swift 1, you can do the following. You use the name just once, but put a "#" character just before the name:

func addTwoNumbers (#first: Int, # second: Int) -> Int {

var c = first + second

return c

}

However, the hash symbol does not work for this purpose in Swift 2. You have to specify the name of the first parameter twice. In the case of the second (and further) parameters, you need specify it only once.

It should be recognized that the parameter names and values must be in the order specified in the function definition. Just because you are using a name for each parameter does not mean that you can put them in any order.

In Swift 2, you can declare a function so that external parameter names are not required, using an underscore character:

func addTwoNumbers (a: Int, _ b: Int) -> Int {

var c = a + b

return c

}

This is called with:

var d = addTwoNumbers (2, 5)

In the case of the first parameter, the parameter name in the call is not required by default. In the case of the second parameter, the underscore indicates that a parameter name is not required (and cannot be used.)

Making an Input Parameter a Variable

It is not possible, in the default case, to modify the value of an input parameter of a function from within that function. An input parameter is by default a constant. However, the input parameter can be modified if it is declared a variable by using the var keyword before it in the definition of the function:

func addTwoNumbers (var a: Int, b: Int) -> Int {

a = a + 5 // Now allowed to modify a

var c = a + b

return c

}

Thus, the input parameter with the name a can now be modified.

This can also be done if an external parameter name is used:

func addTwoNumbers (var first a: Int, b: Int) -> Int {

a = a + 5 // Now allowed to modify a

var c = a + b

return c

}

In-Out Parameters

Normally, a function cannot change the value of a variable that is passed to a function as an input parameter, at least when accessing it as an input parameter. And it is not a good idea for a function to be modifying variables that are in the scope of its calling statement—that breaks the usual assumption of loose coupling and modularity that object-oriented programming is supposed to be based on.

If, however, we want to do this we can do it in a clear and explicit way by declaring a parameter as an in-out parameter.

Thus, if our addTwoNumbers function is called as follows:

var m = 5

var d = addTwoNumbers(2, b: m)

The addTwoNumbers function cannot change the value of m.

However, if we, in the addTwoNumbers function, add the keyword inout before the name of an input parameter, that parameter becomes an in-out parameter. The variable appearing in the calling function corresponding to the in-out parameter can now be modified by the function.

func addTwoNumbers ( a: Int, inout b: Int) -> Int {

b = 7

var c = a + b

return c

}

The way that we call it is slightly different. We use an ampersand in front of the variable name for the in-out parameter because we are passing it by reference (rather than making a copy):

var m = 5

var d = addTwoNumbers(2, b: &m)

In this situation, we've changed the value of b (which was 5) to 7. And so the function will return the value of 9, rather than 7. But beyond this, because we have declared b as an in-out parameter, the variable (outside the function) that was in the calling statement, m, will also have its value changed to 7.

print (m) // Prints: 7

Setting Parameters to Default Values

It is possible to set a default value for an input parameter, by appending an equals sign and a value to the definition of an input parameter:

func addTwoNumbers (a: Int, b: Int = 7) -> Int {

var c = a + b

return c

}

var d = addTwoNumbers(1)

print(d) // Prints: 8

Parameters that have default values should be put at the end of the list of parameters. If an input parameter does not have an external name, Swift will assume one based on the local name so that it can be clear which parameter is being included, should the call provide a value for a parameter that has a default supplied in the function definition.

Variadic Parameters

A variadic parameter has a variable number of input values.

A variadic parameter is indicated by specifying an ellipsis (three periods, or dots) after the input type.

I have modified the addTwoNumbers function to create a function named addAllNumbers that can take any number of input values:

func addAllNumbers (numbers: Int...) -> Int {

var c = 0

for number in numbers {

c = c + number

}

return c

}

var d = addAllNumbers(1,2,3,4)

print(d) // Prints: 10

The original version of this function specified its input parameters as (a: Int, b: Int). In the new function, instead of listing specific input parameters, the name numbers refers to an array. The type is specified with three periods following it to indicate that this is a variadic parameter. All of the input parameter values that are part of a variadic parameter must be of the same type.

In the body of the function, individual parameters are referred to by addressing elements in the array, starting with an index of 0. Or the entire array can be iterated through, as shown here.

If there are only two numbers, the function still makes sense.

var d = addAllNumbers(2, 5) // Result is 7

But there can be any number of input parameters:

var d = addAllNumbers(2) // Result is 2

var d = addAllNumbers(2, 7, 8, 34, 54) // Result is 105

var d = addAllNumbers() // Result is 0

There can be only one variadic parameter for a given function. If there are other input parameters, the variadic parameter must come last.

Hands-On Exercises

Go to the following web address with a Macintosh or Windows PC to do the Hands-On Exercises.

For Chapter 22 exercises, go to

understandingswiftprogramming.com/22