3

I'd like to add a custom init method to the Array class in swift using an extension, but the key is I'd like to add it only to arrays of bytes (UInt8)

I've currently got something like this:

public class MyData {
}

public func toByteArray(myData: MyData) -> [UInt8]? { // a global function
    // code to check if myData is valid, and extract byte array
}

It seems like the more "swifty" thing to do is use a failable initializer, so I'd like to write it like this

extension Array where Element : UInt8 {
    init?(myData: MyData) {
        // code to check if myData is valid, and extract byte array
    }
}

This code doesn't compile though, I get Type 'Element' constrained to a non-protocol type 'UInt8'

I've found other things where you don't extend Array, you instead extend _ArrayType, but this doesn't seem it'll work for initializers

Community
  • 1
  • 1
Orion Edwards
  • 121,657
  • 64
  • 239
  • 328
  • 1
    http://stackoverflow.com/a/34079948/2303865 – Leo Dabus Jul 04 '16 at 21:39
  • How would you use such an extended array type ? let a = Array(myData: yourData) seems worst than your toByteArray() function. Or perhaps you should just give that function a more meaningful name such as UInt8Array(myData:) – Alain T. Jul 05 '16 at 00:58

1 Answers1

0

The only way to achieve this is Swift 2.2 is to make a protocol that UInt8 conforms to and use it into the Array extension as a constraint.

protocol UInt8Protocol {}
extension UInt8 : UInt8Protocol {}

extension Array where Element : UInt8Protocol {

    init?(myData: MyData) {
        ...
    }
}

Into the Swift evolution list it is mentioned that, this (constrained extension using a same-type constraint) is a highly-requested feature. It might be part of one of the next versions of Swift.

itskoBits
  • 435
  • 4
  • 13