Reputation: 135
how to get a first item in empty list to use guard let
or if let
.
For example, I have an empty list and I would like to get gracefully first item in list like here, but it looks like:
var empty_array: [Int] = []
guard let first = empty[0] as? Int else{
// do something
}
// after operation first should be nil
And my code crashes because first item missed in list and I would like to get result of first item that will be nil. How to do this?
UPDATED: to get first item needs use
guard let first = empty.first as? Int else{
// do something
}
But what about second or third item?
Upvotes: 0
Views: 1920
Reputation: 86651
The reason it crashes is because getting an element from an array using a subscript does not return an optional. If no element exists at the index it simply crashes with index out of bounds. This is in contrast to dictionaries where subscript access returns an optional. The rationale behind this design decision is that, for arrays, unwrapping the optional every time would be a right pain, especially as all you have to do is test the index is in 0 ..< array.count
.
Your guard statement tries to access an array element that does not exist, so it crashes. Also, your guard statement is the wrong way around. The block after the else is what is executed in the exceptional condition.
So, if you use empty_array.first
which does return an optional, you should do this:
guard let first = empty_array.first else { return /* bail out of the function */ }
doSomething(with: first) // first is unwrapped here.
Or use if
if let first = empty_array.first
{
doSomething(with: first) // first is unwrapped here.
}
Or you can test the index to make sure it is in range. Has the advantage of working with any index, not just zero
let index = // Some integer
guard index >= 0 && index < empty_array.count else { return }
doSomething(with: empty_array[index])
Or
guard (0 ..< empty_array.count).contains(index) else { return }
Upvotes: 0
Reputation: 3765
You could either
var empty: [Int] = []
guard let first = empty.first else {
// cast did fail - do any stuff to escape this func or whatever you would like to do
}
// access first here --> first is not nil
or
var empty: [Int] = []
if let first = empty.first {
// access first here --> first is not nil
} else {
// cast did fail - do stuff
}
Upvotes: 1
Reputation: 138041
Use empty.first
, which returns a T?
.
guard let first = empty.first else {
// do something
}
Note that the body of a guard
statement must exit the parent scope. It sounds like your comments have it backwards (first
is nil in the guard
scope, not after it).
Upvotes: 1