mutating keyword

I was studying this page about methods, https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Methods.html#//apple_ref/doc/uid/TP40014097-CH15-ID234, at the section entitled Modifying Value Types from Within Instance Methods. I am confused about the "mutating" keyword. What is the intention behind it and what is it good for? I think this is one of those concepts I'll have to review repeatedly to understand. Can anyone explain the "mutating" keyword simply and concisely? I would really appreciate it.


In that section, why does it talk about modifying value types instead of modifying values? Once a variable or constant is declared as a certain value type (Int for instance), is there any need to change it to a different value type (String for instance)?

They are saying that by using the specific keyword (label/tag/reference/flag/trigger/instruction) 'mutating', you can opt in to mutating behavior for a method via a built-in function - they are not talking about a given keyword that mutates or is mutated.


>In that section, why does it talk about modifying value types instead of modifying values?


I think 'mutating' is about modifying values/properties. Where they talk about types, they explain that their properties can't be modified (from within its instance methods)...


"The

Point
structure above defines a mutating
moveByX(_:y:)
method, which moves a
Point
instance by a certain amount. Instead of returning a new point, this method actually modifies the point on which it is called. The
mutating
keyword is added to its definition to enable it to modify its properties."

The nice thing about Swift’s value types is that you can decide whether they are immutable or mutable at the point you use them. For example, consider the

String
type. You can declare a string variable in two ways:
let immutableString: String = "immutable string"
var mutableString: String = "mutable"
mutableString.appendContentsOf(" string")

This approach is nice for a variety of reasons. Let me know if you want me to go into that aspect of things.

For this to work the compiler has to know which methods of the type can change the state of the type. You declare that via the

mutating
keyword. The keyword has two effects:
  • it requires that the caller call the method only on a mutable value

  • it allows the method implementation to change the state of the value

In short, the

mutating
keyword is what allows the compiler to enforce these requirements.

To expand on the first requirement, both of the following statements work because

hasSuffix(_:)
is a normal method:
print(immutableString.hasSuffix(" string"))
print(mutableString.hasSuffix(" string"))

but the first of this next pair fails because

appendContentsOf(_:)
is a mutating method:
immutableString.appendContentsOf(" string")    // this fails
mutableString.appendContentsOf(" string")

To expand on the second requirement, adding a string extension like this:

extension String {
    mutating func borkString() {
        self = self + " bork bork bork"
    }
}

requires that you use the

mutating
keyword because the code changes the value itself. If you leave off the keyword, you get an error.

OTOH, this extension, which doesn’t mutate the value, doesn’t need the

mutating
keyword:
extension String {
    func borkedString() -> String {
        return self + " bork bork bork"
    }
}

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
mutating keyword
 
 
Q