Reputation: 2193
Given the following types
protocol AProtocol {}
protocol AnotherProtocol {}
class AClass: AProtocol, AnotherProtocol {}
I'm a bit confused why the following throws: "error: cannot convert value of type 'AClass' to specified type 'T'"
class generic<T> where T:AProtocol, T:AnotherProtocol {
let prop: T = AClass()
}
But the following works fine:
class generic<T> where T: AProtocol, T: AnotherProtocol {
let prop: T
init(withProp prop: T) { self.prop = prop }
}
let instance = generic<AClass>(withProp: AClass())
Upvotes: 3
Views: 163
Reputation: 272845
The generic parameters of your class are specified by the users of your class, not you.
You can't say that T
has to be AClass
like you did in your first code snippet that did not compile, because T
is specified by the user. A user of your class might want something like:
let myObject = generic<BClass>()
where BClass
also satisfies the constraints. Then what happens when the user tries to access the property? He will get an instance of AClass
but T
is actually BClass
, so he should really be getting a BClass
. See the contradiction here?
Regarding your comment:
In other words, it is not possible to refer to an implementation of the generic type(s) from inside the implementation of the generic class?
Exactly, because you don't know what those types are going to be. You can call methods declared in AProtocol
and AnotherProtocol
though. The generic constraints ensure that those methods exist.
If you want to make it work the way you want, you need what's called protocol composition:
var someProperty: (AProtocol & AnotherProtocol) = AClass()
Upvotes: 4