Given:
protocol MyProtocol {
typealias T
var abc: T { get }
}
And a class that implements MyProtocol:
class XYZ: MyProtocol {
typealias T = SomeObject
var abc: T { /* Implementation */ }
}
How can I define an array of objects conforming to MyProtocol
?
var list = [MyProtocol]()
Gives (together with a ton of SourceKit crashes) the following error:
Protocol 'MyProtocol' can only be used as a generic constraint because it has Self or associated type requirements
Even though the typealias is in fact defined in MyProtocol
.
Is there a way to have a list of object conforming to a protocol AND having a generic constraint?
An array that conations class type elements are known as an array of objects. It stores the reference variable of the object. Before creating an array of objects, we must create an instance of the class by using the new keyword.
In an array of objects, the data can be accessed randomly by using the index number. Reduce the time and memory by storing the data in a single variable. Writing code in comment?
They can be used to store the collection of primitive data types such as int, float, double, char, etc of any particular type. To add to it, an array in C/C++ can store derived data types such as structures, pointers, etc.
The problem is about using the generics counterpart for protocols, type aliases. It sounds weird, but if you define a type alias, you cannot use the protocol as a type, which means you cannot declare a variable of that protocol type, a function parameter, etc. And you cannot use it as the generic object of an array.
As the error say, the only usage you can make of it is as a generic constraint (like in class Test<T:ProtocolWithAlias>
).
To prove that, just remove the typealias from your protocol (note, this is just to prove, it's not a solution):
protocol MyProtocol {
var abc: Int { get }
}
and modify the rest of your sample code accordingly:
class XYZ: MyProtocol {
var abc: Int { return 32 }
}
var list = [MyProtocol]()
You'll notice that it works.
You are probably more interested in how to solve this problem. I can't think of any elegant solution, just the following 2:
T
with AnyObject
(ugly solution!!)but as you may argue, I don't like any of them. The only suggestion I can provide is to rethink of your design and figure out if you can use a different way (i.e. not using typealiased protocol) to achieve the same result.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With