我在Swift上为owner / ownee方案建模:
class Owner<T: Ownee> { // ... } protocol Ownee { var owner: Owner<Self> { get } }
然后我有一对班级教授/学生坚持上面的建模类型:
class Professor: Owner<Student> { // ... } class Student: Ownee { let professor: Professor var owner: Owner<Student> { // error here (see below) return professor } init(professor: Professor) { self.professor = professor } }
但是,我在Student类的var owner定义中收到以下错误:
Protocol ‘Ownee’ requirement ‘owner’ cannot be satisfied by a
non-final class (‘Student’) because it uses ‘Self’ in a non-parameter,
non-result type position
我正在试图理解这个错误的原因是什么,为什么让学生最终的类会修复它,如果有一些解决方法能够以不同的方式对其进行建模,而不会使这个类最终.我已经用Google搜索了这个错误,但到目前为止还没有找到太多.
错误是正确的.您必须使您的课程成为最终,因为没有子类可以符合您的协议Ownee.
考虑这个子类:
class FirstGradeStudent: Student { // inherited from parent // var owner: Owner<Student> { // return professor // } }
如您所见,它必须实现var owner:Owner< Student>因为他的父母,但它应该实现var所有者:所有者< FirstGradeStudent>相反,因为协议包含var owner:Owner< Self> {get}在这种情况下,Self将成为FirstGradeStudent.
1:为Ownee定义一个超类,它应该由所有者使用:
class Owner<T: OwneeSuper> { // ... } protocol OwneeSuper {} protocol Ownee: OwneeSuper { associatedtype T: OwneeSuper var owner: Owner<T> { get } }
OwneeSuper只是克服this problem的一种解决方法,否则我们只会使用:
protocol Ownee { associatedtype T: Ownee var owner: Owner<T> { get } }
2.在符合Ownee的类中,必须通过定义类型来将关联类型的抽象类型转换为具体类:
class Student: Ownee { typealias T = Student // <<-- define the property to be Owner<Student> let professor: Professor var owner: Owner<T> { return professor } init(professor: Professor) { self.professor = professor } }
class FirstGradeStudent: Student { func checkOwnerType() { if self.owner is Owner<Student> { //warning: 'is' test is always true print("yeah!") } } }