1

I was using _ArrayType in my project when I was running on swift 2.1. I upgraded to swift 3.0.2 (Xcode 8.2.1) last week and I found here that _ArrayType is changed to _ArrayProtocol and it was working well.

Today I upgraded my Xcode to 8.3.1, and it gives me error: Use of undeclared type '_ArrayProtocol'. Here is my code:

extension _ArrayProtocol where Iterator.Element == UInt8 {
    static func stringValue(_ array: [UInt8]) -> String {
        return String(cString: array)
    }
}

What's wrong now? Why _ArrayProtocol is undeclared in swift 3.1 while it was working in swift 3.0.2.

Also when I look here in git I see _ArrayProtocol available. Than I looked into Swift 2.1 docs I am able to see '_ArrayType' in protocol listing but in Swift 3.0/3.1 docs I am not able to see _ArrayProtocol.

Community
  • 1
  • 1
Kapil Choubisa
  • 4,970
  • 8
  • 59
  • 99

1 Answers1

2

Type names starting with an underscore should always treated as internal. In Swift 3.1, it is marked as internal in the source code and therefore not publicly visible.

Using _ArrayProtocol was a workaround in earlier Swift versions where you could not define an Array extension with a "same type" requirement. This is now possible as of Swift 3.1, as described in the Xcode 8.3 release notes:

Constrained extensions allow same-type constraints between generic parameters and concrete types. (SR-1009)

Using the internal protocol is therefore not necessary anymore, and you can simply define

extension Array where Element == UInt8 {

}

But note that your static func stringValue() does not need any restriction of the element type. What you perhaps intended is to define an instance method like this:

extension Array where Element == UInt8 {

    func stringValue() -> String {
        return String(cString: self)
    }

}

print([65, 66, 67, 0].stringValue()) // ABC

Also note that String(cString:) expects a null-terminated sequence of UTF-8 bytes.

Martin R
  • 488,667
  • 78
  • 1,132
  • 1,248