This strikes me as something that is more or less by design. Especially in an instance like this, but really in most instances, iterating over a set of value types with the intent to mutate them imperatively is a recipe for somewhat opaque, difficult to debug, and difficult to optimize code (both from the programmer's perspective and the compiler's). There are all kinds of scenarios where you could pull the metaphorical rug out from under yourself or have values that don't make sense because of the way your iteration was handled.
Instead of coming at this situation from an imperative perspective, are you able to come at it instead from a more functional one by using map? That strikes me as the Swifty approach here.
Currently, iterating over indices is the correct solution. What you wrote will work for Array. However, there are some important reasons that it will not work for other collections.
Most collections do not have 0-based indices, so iterating over 0..<count is wrong. For example, if you are working with an ArraySlice, such as alphabet[5..<10], then the indices are actually 5..<10 (slices share indices with their base collection).
It would be tempting to iterate over the indices property, but you should not do that either, because some collections such as Dictionary.Values are retained by their indices, and thus mutating the collection while iterating over indices would make an extra copy of the entire collection.
The correct, general solution looks like this:
var i = alphabet.startIndex
while i != alphabet.endIndex {
alphabet[i] += " is a letter"
alphabet.formIndex(after: &i)
}
If you want to encapsulate this functionality into a method available on all mutable collections, it would look like this:
extension MutableCollection {
mutating func mutateEach(transform: (inout Element)->Element) {
var i = startIndex
while i != endIndex {
transform(&self[i])
formIndex(after: &i)
}
}
}