SLN SLN - 5 months ago 14
Swift Question

What are the benefits of type constraints in protocol extensions?

I'm a programming beginner, please excuse the naive question. Swift is my first language and I have no reference (other programming languages) to compare the benefits of the type Constrains on protocol extension.

Personally, I just feel confused and weird. Why the Type constraint on a protocol extension exist? What's the meaning of it?

protocol TeamRecord {
var wins: Int { get }
var losses: Int { get }
func winningPercentage() -> Double
}

//Constraint:
extension CustomStringConvertible where Self: TeamRecord {
var description: String {
return "\(wins) - \(losses)"
}
}

struct BaseballRecord: TeamRecord {
var wins: Int
var losses: Int

func winningPercentage() -> Double {
return Double(wins) / Double(wins) + Double(losses)
}
}

extension BaseballRecord: CustomStringConvertible { }

print(BaseballRecord(wins: 4, losses: 2))


Question I feel weird to use the
where Self
constraint here, what's the benefits of it? Can we achieve the same result without using the constraint staff?

Thanks so much for your time and help

Answer

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.

Comments