Reputation: 5597
I just cannot understand why this causes errors (errors shown as comments in code):
class SomeClass {
var id = 123
}
class AnotherClass {
func myFunc<T>(object: T) {
T.id = 555 // Error: Type 'T' has no member 'id'
object.id = 555 // Error: Value of type 'T' has no member 'id'
}
}
let someClass = SomeClass()
let anotherClass = AnotherClass()
anotherClass.myFunc(someClass)
How do you get the instance of someClass after passing it into the generic function?
Also, I can't do any named downcasting inside AnotherClass (as you would expect with a generic).
Upvotes: 1
Views: 1918
Reputation: 57114
You have to look up a little bit more about generics. T
has no member called id
- that is correct! Just because you pass in some T that has a member (SomeClass) that does not matter for the compiler since at some other point you can insert something else like a Int
or [Double]
or anything.
Consider adding the following line to your code
anotherClass.myFunc(1)
What should happen? What should .id
do??? It would fail because 1 does not have a member called id
.
Your T
has no generic constraint telling the compiler anything, therefore it assumes you can just pass in anything. And then you can only use all those properties the possible inputs share.
What you might want to use is for example
func myFunc<T : SomeClass>(object: T) {
object.id = 555
}
That tells the compiler that you are only allowed to pass in objects of type SomeClass
or classes that extend SomeClass
. Following the logic from above the compiler can look at the code, all possible inputs and allows you to perform the operations that are valid on all possible inputs. Therefore the compiler knows that the id
property exists since SomeClass
has it and all classes extending SomeClass
do as well, since that is how extending works.
Once again the apple docs on generics are a really good place to learn a lot about generics from the basics to the quite complex use-cases.
Upvotes: 5