0

The code below fails to compile, but I'm not sure what to do to get it to compile and run. Paste in a playground to try it out. I expect it to print "configured" twice. My question is not a duplicate of this. I don't have an array of things that all conform to the protocol. I want to test to see if they conform and only call the method if they do.

My goal is to have it call configure on any object in the array that can handle a MyConfiguration object, otherwise do nothing. Any ideas?

protocol Configurable {
    associatedtype Configuration
    func configure(with configuration: Configuration)
}


struct MyConfiguration { }

class Base { }

class A: Base, Configurable {
    func configure(with configuration: MyConfiguration) {
        print("configured")
    }
}

class B: Base { }

extension Array where Iterator.Element == Base {

    func configure(with configuration: MyConfiguration) {
        for each in self {
            if let configurable = each as? Configurable {
                configurable.configure(with: configuration)
            }
        }
    }
}

let array: [Base] = [A(), B(), A()]
let conf = MyConfiguration()

array.configure(with: conf)
Daniel T.
  • 32,821
  • 6
  • 50
  • 72
  • 1
    Possible duplicate of [Protocol can only be used as a generic constraint because it has Self or associatedType requirements](https://stackoverflow.com/questions/36348061/protocol-can-only-be-used-as-a-generic-constraint-because-it-has-self-or-associa). Also have a look at type erasure, that's the usual method to solve such an issue as yours. Moreover if you have a debugging question, you should include the actual error rather than just saying the code fails to compile... – Dávid Pásztor Nov 05 '17 at 17:53
  • The problem here is that I don't have an array of things that all conform to the protocol. I want to test to see if they conform. Type erasure would work if all the elements in the array conformed to the protocol, but they don't. My question is different. – Daniel T. Nov 05 '17 at 17:58
  • As written, even if Swift had existential types (which it may have some day, but doesn't currently), this could never work. What do you expect to happen if one of the elements were `Configurable` but with something other than `MyConfiguration`? You're always passing `MyConfiguration`, but you're not checking that it accepts that type. Did you really mean to have an associated type here? How do you expect it to work when it's some other configuration object? If you get rid of the associated type, this becomes much simpler. If you keep it, you need to deal with that case. – Rob Napier Nov 05 '17 at 18:06
  • My goal is to have it call configure on any object in the array that can handle a MyConfiguration object, otherwise do nothing. I'm open to any suggestions. – Daniel T. Nov 05 '17 at 18:08

0 Answers0