I am writing Go code in a private context for about one year now and recently I have stepped over a minor inconsistency regarding slices. So basically as maps, channels and type-assertions have an option for a ‘two value read’ -> val, ok := myMap[key]
why not adding a similar functionality for slices?
This would look like this val, ok := mySlice[n]
. If the requested index n
is not present val
will be assigned the zero-value and ok
will be false
.
Yes you can in fact create your own function that does exactly this in 4 loc.
func safeSliceAccessInt(sl []int, idx int) (int, bool) {
defer func() { recover() }()
return sl[idx], true // default values will be substituted if sl[idx] panics (0, false)
}
But of course this is a not generic approach.
I argue more from a consistency aspect than an actual feature one.
Regarding arrays I would suggest against this behaviour as their range can be deduced by their type.
I think this would be very Go idiomatic but still I am not fully convinced myself as wether this is a good idea or not as it introduces redundant behaviour (can be easily archived using the above function or checking the slice bounds with len
).
Feature wise it gives you an easy way to bypass the bounds check panic.
As stated above this would fit nicely as map, type-assertion and channel provide similar functionality.
No code will be broken as the single value context assignment will be picked in multi assignment context -> a, b := mySlice[n], 5
will result in b == 5 like with maps, channels and type-assertions.
Maybe we could return the actual value at the position like in C as the bool will be false indicating it is not part of the slice. Out-of-bound writes will of course still panic. I don’t think this fits well into Go but maybe worth a thought.
Please discus.
Update: Additional example in the comments.