I have a mixin that prints the assigns the class name as a String
to an instance variable.
import Foundation
protocol Recyclable {
static var name: String { get }
}
extension Recyclable {
static var name: String {
return String(describing: Self.self)
}
}
There are two classes that implement the mixin:
class One: NSObject, Recyclable { }
class Two: NSObject, Recyclable { }
So if I want to print the class name, I can just
One.self.name // "One"
This works perfectly. Now let's get deeper.
Putting this into a function to print the name of all given classes. It needs to be a generic, since it can accept any class that conforms to the Recyclable protocol
.
func printAllNames<T: NSObject>(_ things: T.Type...) where T: Recyclable {
for thing in things {
print(thing.name)
}
}
If I use this for one class only, it works as expected.
printAllNames(One.self) // "One"
But when used with more than one, it errors out
printAllNames(One.self, Two.self)
Playground execution failed: error: GenericMixins.playground:20:1: error: generic parameter 'T' could not be inferred printAllNames(One.self, Two.self)
Any hints on what might be happening?
Playground: https://www.dropbox.com/sh/q0b5b3oo0luj471/AABSG2QEOIj_SBsvtv7cEv-Ka?dl=0
I ended up figuring it out. The right approach is to make function accept anything, and then check if what was accepted conforms to the protocol.
The function should be
func printAllNames(_ things: AnyObject...) {
for thing in things {
if let klass = thing.self as? Recyclable.Type {
print(klass.name)
}
}
}
And then it works as expected
printAllNames(One.self, Two.self)
One
Two
Updated playground: https://www.dropbox.com/sh/9sjboo3lfu83662/AAC9CKn_dU_wrihCvKUfujQ7a?dl=0