Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mutate function parameters in Swift

Tags:

swift

Is it possible mutating what variables passed as arguments to a function, point to, as their value, within the scope of that function, in Swift?

func exampleFunction(value: String, index: Int) -> Bool {
    value = "Changed Value" // Error
    index = 3  // Error

    return true
}

Calling it by:

var flag = exampleFunction("Passed Value", 2)

Is it possible to mutate the arguments passed as parameters, while within the scope of exampleFunction? if not, is there any other way to do this? Because using this we only change value of temp.

var temp = value
temp = "temp Change"
like image 216
Mohit Jethwa Avatar asked Jun 27 '14 12:06

Mohit Jethwa


People also ask

What is a mutating function in Swift?

What can a mutating function do? Essentially, a function that's been marked as mutating can change any property within its enclosing value. The word “value” is really key here, since Swift's concept of structured mutations only applies to value types, not to reference types like classes and actors.

Can we pass function as a parameter in Swift?

To pass function as parameter to another function in Swift, declare the parameter to receive a function with specific parameters and return type. The syntax to declare the parameter that can accept a function is same as that of declaring a variable to store a function.

What is Inout in Swift?

Swift inout parameter is a parameter that can be changed inside the function where it's passed into. To accept inout parameters, use the inout keyword in front of an argument. To pass a variable as an inout parameter, use the & operator in front of the parameter.

What is parameter in Swift?

Parameters can provide default values to simplify function calls and can be passed as in-out parameters, which modify a passed variable once the function has completed its execution. Every function in Swift has a type, consisting of the function's parameter types and return type.


3 Answers

It seems from your example that you need to change the passed arguments inside the function as a side effect, and need the updated values to be available after the function call. If that's the case, you need to use the inout modifier.

Otherwise, if all you need is to modify the parameters inside of the function call, you can explicitly define them as variables on the function definition:

Using in-out parameters

First, change your function declaration to:

func exampleFunction(inout value: String, index: inout Int) -> Bool

Now, an in-out parameter has a value that is passed in to the function, is modified by the function, and then is passed back out of the function, replacing the original value. For this to work, you can't pass a literal into your function, since there would be nowhere to store the modified value afterwards. In fact, it has to be a variable. You cannot pass a constant or a literal value as the argument, because constants can't be modified. Hence, change your function call to:

var passed = "passedValue"
var index = 2

var b = exampleFunction(&passed, &index)

After the call, both passed and index will contain the new values, as modified by the function.

Also, note the & before each argument when calling the function. It must be there, to indicate the argument can be modified by the function.

Using variable parameters – Removed in Swift 3

In this case, all you need to do is change your function declaration to use variable parameters, as below:

func exampleFunction(var value: String, var index: Int) -> Bool

Changes made to the arguments inside the scope of the function, aren't visible outside the function or stored anywhere after the function call.

like image 138
Cezar Avatar answered Oct 04 '22 01:10

Cezar


If it's just for the function scope, you can declare your function as

func exampleFunction(var value : String, var index : Int) -> Bool { }

Note - However that was removed in Swift3.

Simply add a var ..

func exampleFunction(value : String, index : Int) -> Bool {
      var value = value
      var index = index

indeed, the Xcode IDE will autofix that for you.


If your intention is to modify the parameters in their global context, you can use inout.

like image 26
Nicolai Avatar answered Oct 04 '22 00:10

Nicolai


var Parameter is deprecated and will be removed from Swift 3.0. If you want to change the parameter inside your function body you should store the passed parameter in some local variable and change it

    func exampleFunction(var value: String, var index: Int) -> Bool {
       var index = index
       ...
    }

inout Parameter is still there though. So if you want that the changes that you make to the passed parameter should be reflected outside the function body, you should be using inout Parameter.

like image 21
Mohammad Sadiq Avatar answered Oct 04 '22 01:10

Mohammad Sadiq