如何从 Generic 获取实例?

use*_*356 1 generics swift

我只是不明白为什么这会导致错误(错误在代码中显示为注释):

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)
Run Code Online (Sandbox Code Playgroud)

将 someClass 的实例传递给泛型函数后如何获取它?

此外,我无法在 AnotherClass 中进行任何命名向下转换(正如您对泛型所期望的那样)。

luk*_*302 5

你必须多查一点关于泛型的信息。T没有成员被调用id- 这是正确的!仅仅因为你在传递一些牛逼具有不要紧,编译器的成员(SomeClass的),因为在其他一些时候,你可以插入别的东西像Int或[Double]什么的。

考虑将以下行添加到您的代码中

anotherClass.myFunc(1)
Run Code Online (Sandbox Code Playgroud)

应该发生什么?应该.id怎么办???它会失败,因为 1 没有名为 的成员id。

您T没有告诉编译器任何内容的通用约束,因此它假设您可以传入任何内容。然后您只能使用可能的输入共享的所有这些属性。

例如,您可能想要使用的是

func myFunc<T : SomeClass>(object: T) {
    object.id = 555
}
Run Code Online (Sandbox Code Playgroud)

这告诉编译器你只允许传入SomeClass扩展类型或类的对象SomeClass。按照上面的逻辑,编译器可以查看代码、所有可能的输入,并允许您对所有可能的输入执行有效的操作。因此,编译器知道该id属性存在,因为SomeClass拥有它,并且所有扩展的类SomeClass也是如此,因为这就是扩展的工作方式。

再一次,关于泛型的苹果文档是一个非常好的地方,可以从基础知识到非常复杂的用例学习很多关于泛型的知识。