Reputation: 961
I'm coming from a Javascript background and I'm looking for some clarity on inout with Swift.
In Javascript, a function's parameter only exists within the scope of that function. So for instance I could do this without a problem.
function greet(name) {
name = "randomDude";
return name
}
greet("Barry");
This works because the parameter name only exists within the scope of the greet function. So I can change the value of name.
However, in Swift, I cannot do this:
func greet(name: String) {
name = "Ardvark"
print(name)
}
greet(name: "Drew")
The solution would be to change it to an 'inout' function, which can only take a variable, i.e.:
func greet(name: inout String) {
name = "Ardvark"
print(name)
}
var name = "Drew"
greet(name: name)
However, when I do this, it actually CHANGES the value of var name. Meaning the inout function doesn't modify only the value of the PARAMETER within the scope of the function, but modifies the global variable.
Is this just something I have to accept? Is there a reason it modifies the global variable? How would you modify only the variable 'name' inside the function greet?
Thanks
Upvotes: 1
Views: 286
Reputation: 961
Just read some of the Swift docs. Came to two conclusions.
(1) By default, parameters in Swift are CONSTANTS, so it's as if there is a let keyword before the parameter. Meaning inside the function, the parameter value cannot be changed, or an error will be thrown.
(2) Changing your function to an 'inout' function changes things. First off, it removes the 'let' constraint. Secondly, when you pass in an argument to the inout parameter, it is known as copy-in, copy-out. The argument's value is copied in memory, passed through the function, modified in the function, and the new value is assigned to the original variable that was passed as an argument.
These are two distinct types of functions if you think about it. In other words, there is no functionality like in Javascript where you can simply modify the parameter's value inside the scope of the function ONLY.
Because:
The parameter is either a CONSTANT (by default),
OR...
You are using an inout function, in which case, the parameter is a variable as opposed to a constant, but that parameter only exists for the purpose of 'transferring' an argument's original value into a function where it can be modified, and then spit back out as a new value to the original variable placeholder in memory.
In other words... There is no way (that I know of) in Swift to only modify a parameter's value INSIDE the scope of it's function. You are either prohibited from doing so by default because the parameter is a constant, or you are using an inout function, which isn't modifying the parameter's value inside the function only... It is modifying the GLOBAL namespace's value.
Upvotes: 0
Reputation: 318814
The reason the 2nd block of code (1st Swift example) prevents you from changing the value of name
is because in Swift 3, all parameters are constants. In other words they are essentially all declared with let
.
Imagine your first Swift example as:
func greet(let name: String) {
name = "Ardvark"
print(name)
}
Obviously you don't really put let
there but that will help you remember that parameters are immutable. This prevents you from changing the value by mistake. If you want to change it just inside the function, use a new variable:
func greet(name: String) {
let anotherName = "Ardvark"
print(anotherName)
}
Using inout
changes the parameter by "removing the let" and allowing you to change the original variable used when calling the function.
How would you modify only the variable 'name' inside the function greet?
You don't in Swift 3. The parameter is immutable. Assign it to a new variable inside the function.
Upvotes: 5
Reputation: 2327
In the func greet(name: String) {}
function name
is a constant, actually it looks like func greet(let name: String) {}
so you can't modify it. Let add a new variable and assign value of name
to it:
func greet(name: String) {
var newName = name
newName = "Ardvark"
print(newName)
}
Upvotes: 2