[swift-evolution] Optional safe subscripting for arrays
Maximilian Hünenberger
m.huenenberger at me.com
Sat Jan 16 19:55:18 CST 2016
It is true that the setter could cause some confusion in the first place but I think of these particular setters as optional chaining:
person.residence?.address = "1 Infinite Loop"
Where the `address` is not set when `residence` is nil. So it's like the array is nil/not defined if you access it out of bounds.
In addition subscripts imply O(1) access/set so the expanding array setter should be implemented as method.
- Maximilian
> Am 17.01.2016 um 02:29 schrieb davesweeris at mac.com:
>
> I’m definitely +1 on the getter. I have reservations on the setter. As described, this code:
> subscript(safe index: Index) -> Element? {
> return self.indices ~= index ? self[index] : nil
> }
> subscript(clamp index: Index) -> Element? {
> get { return self.indices ~= index ? self[index] : nil } // again, because subscripts can’t be setter-only
> set {
> if self.indices ~= index {
> self[index] = newValue!
> } else {
> self.append(newValue!)
> }
> }
> }
>
> Would lead to some counter-intuitive results.
> var foo = [0, 1, 2]
> print(foo[safe: 2]) // Optional(2)… Yep
> foo[clamp: 6] = 6
> print(foo[safe: 6]) // nil… Wait, what? I just set that to 6! Why is it nil now?
>
>
> Instead of just appending the new value, we could extend the array to the required capacity:
> subscript(safe index: Index) -> Element? {
> get { return self.indices ~= index ? self[index] : nil }
> set {
> if self.indices ~= index {
> self[index] = newValue!
> } else {
> while !(self.indices ~= index) {
> self.append(newValue!)
> }
> }
> }
> }
>
> The results could still be unexpected:
> var foo = [0, 1, 2]
> print(foo) // [0, 1, 2]… Yep
> foo[safe: 9] = 9
> print(foo[safe: 9]) // Optional(9)… Yep
> print(foo) // [0, 1, 2, 9, 9, 9, 9, 9, 9]… Wow, that’s bigger than I thought
>
> but at least you’d be able to read from the index to which you just wrote.
>
> - Dave Sweeris
>
>> On Jan 16, 2016, at 14:08, Maximilian Hünenberger via swift-evolution <swift-evolution at swift.org> wrote:
>>
>> I've also thought of this. But the concept of safe indexing can also be extended to CollectionType (or to the more abstract Indexable protocol) where it's index is Comparable.
>>
>> For mutable Collections/MutableIndexable there could be two versions of a safe subscript set:
>>
>> array[safe: 5] = 7 // does nothing if index out of bounds
>>
>> array[clamp: 5] = 7
>> // if array is empty: does nothing
>> // if 5 >= array.endIndex : sets last element
>> // if index < 0 : sets first index
>>
>> So definitely worth considering.
>>
>>
>> - Maximilian
>>
>>> Am 16.01.2016 um 21:44 schrieb Rudolf Adamkovič via swift-evolution <swift-evolution at swift.org>:
>>>
>>> Hi there!
>>>
>>> From time to time, I find myself using safe subscripting, e.g.:
>>>
>>> let array = [1, 2, 3]
>>>
>>> array[safe: 0] // 1
>>> array[safe: 1] // 2
>>> array[safe: 2] // 3
>>> array[safe: 3] // nil
>>>
>>> … with the following implementation:
>>>
>>> subscript (safe index: Int) -> Element? {
>>> return self.indices ~= index ? self[index] : nil
>>> }
>>>
>>> I was wondering … wouldn’t it be handy to have this in the standard library?
>>>
>>> Best regards,
>>> Rudolf Adamkovic
>>>
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution at swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160117/7593cad3/attachment-0001.html>
More information about the swift-evolution
mailing list