Cristian
Cristian

Reputation: 666

Can't Subscript from swift extension

This is the problem:

typealias Byte = UInt8

protocol ByteProtocol {}
extension UInt8: ByteProtocol {}

extension Array where Element: ByteProtocol  {

    subscript (index: Int) -> UInt8 {
        return self[Int(index % self.count)]
    }

}

This gives me Overflow even if it is mathematically impossible:

var p: [Byte] = [Byte]()
p.append(15)
print(p[10])

So what is the mistake here? P.S. Thank you for your answer :)

Upvotes: 0

Views: 1228

Answers (3)

Rob Napier
Rob Napier

Reputation: 299355

You can't overload subscripts this way. Even if you could, you'd be creating an infinite loop in your implementation. Your implementation also would be illegal, since it returns something other than Element.

What you mean is something like this:

extension Array where Element: ByteProtocol  {

    subscript (wrapping index: Int) -> Element {
        return self[Int(index % self.count)]
    }
}

var p: [Byte] = [Byte]()
p.append(15)
print(p[wrapping: 10])

Upvotes: 5

matt
matt

Reputation: 535231

It doesn't give you an "overflow". It gives you an out-of-range error. There is no element index 10 in an array with only 1 element. The crash occurs before your subscript implementation is ever called (as you could easily discover by breakpointing it). You cannot magically change the meaning of an existing subscript implementation in the way you are hoping to.

Upvotes: 1

Alexander
Alexander

Reputation: 63271

The default implementation of subscript is called, not yours. Hence, it's trying to actually access the 10th element, which doesn't exist.

You can't override the behaviour of a struct like Array using an extension. They're not polymorphic. You can, however, add a new definition of a subscript, as rob showed.

Upvotes: 0

Related Questions