The underscore (in this situation) tells the compiler that there is something there, but you don't need access to it in your code by name. There's a link with more details in the comments to your question, but let's look at the effect it has on the code in question.
Seeing the code formatted might help it to be more clear:
var abc = ["A", "B", "C", "D"]
var number = ["1", "2", "3"]
for i in 0 ..< abc.count {
var str = "\(abc[i])"
for _ in 0..<2 {
str += " \(number[i])"
}
print(str)
}
In this example, the outer for
loop stores its index in I
. The inner for loop has an index, but the _
is basically saying (I'm okay ignoring this for now). The loop still runs, but the index isn't being used anywhere.
The reason this results in a runtime error is because abc
has more elements than number
. So, when the inner loop tries to access number[3]
when i
is 3
, there's a crash.
Now, let's look at the second example:
var abc = ["A","B","C","D"]
var number = ["1","2","3"]
for i in 0..<abc.count {
var str = "\(abc[i])"
for i in 0..<2 {
str += " \(number[i])"
}
print(str)
}
In this example, i
is used in both the outer and inner loops. This is sometimes called variable shadowing and is generally a bad idea, because it can lead to very confusing situations where it's easy to mistake what variable is being read. For example, here, in the scope of the outer loop, i
means one thing, but then in the scope of the inner loop, it means something else.
It would be more clear like this:
for i in 0..<abc.count {
var str = "\(abc[i])"
for j in 0..<2 {
str += " \(number[j])"
}
print(str)
}
Now, on the outer loop, i
is the index and on the inner one j
is the index.
The two examples may look very similar, but really they function very differently because of the details of how the indexes are used within the loops.