-1
class Human {
    var name : String?
}

class Man : Human {
    var numberOfWallets : Int?
}

class Woman : Human {
    var numberOfPurses : Int?
}

protocol P {
    associatedtype Person : Human
    func printX(of person : Person)
    func printY(of person: Person)
}

Which allows Human to be its typealias:

class C : P {
    typealias Person = Human
    func printX(of person: Human) {
        print(person.numberOfCars)
    }

    func printY(of person: Human) {
        print(person.name)
    }
}

As you can see the Person type is constrained by Human which itself is a concrete type. I'm wondering if this is common. My intuition tells me that it's actually a sign that I shouldn't be use protocols, and rather classes itself are just fine.

or I should just do

protocol P {
    associatedtype Person
    func printX(of person : Person)
    func printY(of person: Person)
}

class C : P {
    func printX(of person: Man) {
        print(person.numberOfCars)
    }

    func printY(of person: Man) {
        print(person.name)
    }
}

Which won't allow a Woman & Man instanced to be simultaneously used against a C instance.

I know it depends on what I want to do. But my question really is: Is constraining an asscoiatedtype with a concrete type ever meaningful?!

Or associatedtypes are just there to be either unconstrained or constrained by a protocol, not a concrete type...

mfaani
  • 33,269
  • 19
  • 164
  • 293
  • They're probably not as common as a protocol-constrained associated types, but class-constrained associated types definitely have valid use cases, in the same way that class-constrained generic placeholders have valid use cases. – Hamish Dec 06 '18 at 13:27
  • So to answer my own question: It's fine to do such. The reason I thought this might not be ok is because I'm new to using PATs and most of Swift documentation is where they are constrained to another protocol. ie I haven't come across an associatedtype constrained by a concrete type... – mfaani Dec 06 '18 at 22:16

1 Answers1

1

In this line

 associatedtype Person : Human

The constraint is not concrete or not. It works in parallel fashion for both kinds of inheritance.

• If Human is a protocol, Person must be a concrete type that adopts it.

• If Human is a class, Person must be a concrete type that descends from it.

Both are useful and legal, and very similar to one another.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • You're explaining what the `:` does. inherits or adopts. My question: Is it common to have your associatedtype based off a concrete type? Have you see instances in Swift/Apple code where they constraint it with a concrete type? Because I haven't seen any... – mfaani Dec 04 '18 at 19:26
  • Swift standard library is all structs (and protocols) so obviously you wouldn’t see class constraints. – matt Dec 04 '18 at 19:59
  • an example of a struct constraint would also suffice to nullify my claim. I mean isn't struct also a concrete type? – mfaani Dec 04 '18 at 20:20
  • No that would make no sense and isn’t legal. Constraints with a colon, as I said in my answer, are about inheritance. Classes and protocols do inheritance, by descent and adoption respectively. Structs don’t. – matt Dec 04 '18 at 20:24