Can I make an Array extension that applies to, for instance, just Strings?
As you may know Swift does not allow stored properties into extensions. That's by design: “Extensions may not contain stored properties.”
In Swift, you can even extend a protocol to provide implementations of its requirements or add additional functionality that conforming types can take advantage of. For more details, see Protocol Extensions. Extensions can add new functionality to a type, but they can't override existing functionality.
In Swift, we can add new functionality to existing types. We can achieve this using an extension. We use the extension keyword to declare an extension. For example, // class definition class Temperature { ... } // extension of Temperature class extension Temperature { // add new methods }
Extensions let us add functionality to classes, structs, and more, which is helpful for modifying types we don't own – types that were written by Apple or someone else, for example.
As of Swift 2, this can now be achieved with protocol extensions, which provide method and property implementations to conforming types (optionally restricted by additional constraints).
A simple example: Define a method for all types conforming
to SequenceType
(such as Array
) where the sequence element is a String
:
extension SequenceType where Generator.Element == String {
func joined() -> String {
return "".join(self)
}
}
let a = ["foo", "bar"].joined()
print(a) // foobar
The extension method cannot be defined for struct Array
directly, but only for all types
conforming to some protocol (with optional constraints). So one
has to find a protocol to which Array
conforms and which provides all the necessary methods. In the above example, that is SequenceType
.
Another example (a variation of How do I insert an element at the correct position into a sorted array in Swift?):
extension CollectionType where Generator.Element : Comparable, Index : RandomAccessIndexType {
typealias T = Generator.Element
func insertionIndexOf(elem: T) -> Index {
var lo = self.startIndex
var hi = self.endIndex
while lo != hi {
// mid = lo + (hi - 1 - lo)/2
let mid = lo.advancedBy(lo.distanceTo(hi.predecessor())/2)
if self[mid] < elem {
lo = mid + 1
} else if elem < self[mid] {
hi = mid
} else {
return mid // found at position `mid`
}
}
return lo // not found, would be inserted at position `lo`
}
}
let ar = [1, 3, 5, 7]
let pos = ar.insertionIndexOf(6)
print(pos) // 3
Here the method is defined as an extension to CollectionType
because
subscript access to the elements is needed, and the elements are
required to be Comparable
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With