How to Add Type Constraints to a Swift Protocol Conformance Extension

Is it possible to add type constraints to a Swift protocol conformance extension?

EDIT: As noted in the updated question, this is now possible since Swift 4.1


This is not currently possible in Swift (as of Xcode 7.1). As the error indicates, you can't restrict protocol conformance ("inheritance clause") to a type-constrained extension. Maybe someday. I don't believe there's any deep reason for this to be impossible, but it's currently not implemented.

The closest you can get is to create a wrapper type such as:

struct FriendlyArray<Element: Friendly>: Friendly {
let array: [Element]
init(_ array: [Element]) {
self.array = array
}
func sayHi() {
for elem in array {
elem.sayHi()
}
}
}

let friendly: Friendly = FriendlyArray(["Foo", "Bar"])

(You would likely want to extend FriendlyArray to be a CollectionType.)

For a tale of my own descent into the madness of trying to make this work, and my crawl back from the edge, see NSData, My Old Friend.

What are the benefits of type constraints in protocol extensions?

Funny enough, the "constraint" actually adds lots of power to extensions.

Without the constraint that the conforming type of CustomStringConvertible be a TeamRecord, the compiler would have no way of guaranteeing that the wins and losses properties will exist.

Type constraints (in general, not just on protocol extensions) do limit the selection of types that can possibly conform to the protocol, but in exchange, they buy you compiler enforcement that whatever properties/methods you invoke will be available in the conforming type.

Consider another example, the keys of a Dictionary must be Hashable. The Dictionary relies on being able to get hash values of keys to determine how to store them. The constraint is very important. Without it, I could try using a custom struct/object as a Dictionary key. My custom struct/object can't be hashed, so what is the program to do?

Adding the constraint gives the compiler additional information to guide me. It'll require me to add conformance to Hashable, and won't compile without it.

Are mixed class/protocol type constraints allowed in Swift protocol extensions?

Try:

extension Protocol2 where Self: UIViewController, Self: Protocol2 {}

Protocol Extension of Constrained Dictionary

Since Swift 4.2 you can do this with:

extension Dictionary : FirebaseValue where Key == String, Value == FirebaseValue {
}

How do you structure generic type protocol conformance in Swift?

protocol SomeModelType {  }

protocol SomeProtocol {

associatedtype T: Any
var someVar: T? { get }
}

class ConcreteClass<T> :SomeProtocol where T: SomeModelType {

var someVar: T?

}

Why do we add protocol conformance with extensions?

They are different coding styles. The first option

class Christmas {
...
}

extension Christmas: Merry {
...
}

is cleaner when you're looking at the whole class. You can instantly see all the protocol implementations the class conforms to.

Using the second option you put the implementation of the protocol inside the class mixing it with the class methods. However, if you use

//MARK: - 

the code becomes not less clean, than when you use extensions. For example:

protocol Merry: class {
func celebrate()
}

class Cristmas: NSObject, Merry {
private var santa: AnyObject?

//MARK: - Private Methods
private func callSanta() {
//calling Santa
}

//MARK: - Merry Implementation
func celebrate() {
//celebration starts here
}
}

and when looking at the whole class you clearly see the separation of the protocol implementation:
Sample Image

The functionality of both options is the same.



Related Topics



Leave a reply



Submit