Swift协议要求只能通过使用最终的类来满足 [英] A Swift protocol requirement that can only be satisfied by using a final class

查看:416
本文介绍了Swift协议要求只能通过使用最终的类来满足的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  class拥有者< T:Ownee> {
// ...
}

协议Ownee {
var owner:Owner< Self> {get}
}

然后我有一对教授/学生坚持上面建模的类型:

  class教授:Owner< Student> {
// ...
}

班级学生:Ownee {
让教授:Professor
var owner:Owner< Student> {//错误在这里(见下文)
回报教授
}

init(教授:教授){
self.professor = professor
}
}

然而,我在 var 学生类中的所有者
$ b


协议' Ownee'要求所有者'不能由
非最终类('学生')满足,因为它在非参数,
非结果类型位置中使用Self


我试图理解这个错误的原因是什么,为什么使类 Student final会解决这个问题,并且如果有一些解决方法能够以不同的方式进行建模,而不需要最终确定这个类。我已经搜索了这个错误,但迄今为止还没有发现。

解决方案

错误是正确的。因为没有任何子类可以符合你的协议 Ownee



考虑这个小类:

  class FirstGradeStudent:Student {
//从父类继承
// var owner:Owner< Student> {
//返回教授
//}
}

正如你所看到的,它必须实现 var owner:Owner< Student> ,因为他的父类,但它应该实现 var owner:Owner< ; FirstGradeStudent> 代替,因为协议包含 var owner:Owner< Self> {get} ,在这种情况下 Self 应该是 FirstGradeStudent



解决方法

<1> 定义超类为 Ownee ,它应该被所有者使用:

  class拥有者< T:OwneeSuper> {
// ...
}

协议OwneeSuper {}
协议Ownee:OwneeSuper {
associatedtype T:OwneeSuper
var owner :所有者< T> {get}
}

OwneeSuper 只是解决方法来克服这个问题,否则我们只会使用:

  protocol Ownee {
associatedtype T:Ownee
var owner:Owner< T> {get}
}

to Ownee ,您必须通过定义 associatedtype 的抽象类型转换为具体类> typealias

  class Student:Ownee {
typealias T = Student //< ;< - 将属性定义为所有者< Student>
让教授:教授
var owner:所有者< T> {
return professor
}

init(教授:教授){
self.professor = professor
}
}

3。子类现在可以使用属性,该属性将是您定义的类型:

  class FirstGradeStudent:Student {
func checkOwnerType(){
如果self.owner是Owner<学生> {//警告:'是'test总是正确
print(yeah!)
}
}
}


I'm modeling a owner/ownee scheme on Swift:

class Owner<T: Ownee> {
     // ...
}

protocol Ownee {
    var owner: Owner<Self> { get }
}

Then I have a pair of classes professor/student that adhere to the modeled types above:

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
    }
}

However I get the following error on the definition of var owner in the Student class:

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

I'm trying to understand what's the cause for this error, why making the class Student final would fix it, and if there's some workaround to be able to model this differently, without making this class final. I've googled about that error, but haven't found much so far.

解决方案

The Error is correct. You have to make your class final, since no subclasses could conform your protocol Ownee.

Consider this subclass:

class FirstGradeStudent: Student {
   // inherited from parent
   // var owner: Owner<Student> {
   //     return professor
   //  }
}

As you can see, it would have to implement var owner: Owner<Student> because of his parent, but it should be implementing var owner: Owner<FirstGradeStudent> instead, because the protocol contains var owner: Owner<Self> { get } and in this case Self would be FirstGradeStudent.

Workaround

1: Define a superclass to Ownee, it should be used by Owner:

class Owner<T: OwneeSuper> {
    // ...
}

protocol OwneeSuper {}    
protocol Ownee: OwneeSuper {
    associatedtype T: OwneeSuper
    var owner: Owner<T> { get }
}

OwneeSuper is just a workaround to overcome this problem, otherwise we would just be using:

protocol Ownee {
    associatedtype T: Ownee
    var owner: Owner<T> { get }
}

2. In classes that conform to Ownee, you must turn the abstract type of the associatedtype into a concrete class by defining a typealias:

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
    }
}

3. Subclasses can now make use of the property, which will be of your defined type:

class FirstGradeStudent: Student {
    func checkOwnerType() {
        if self.owner is Owner<Student> { //warning: 'is' test is always true
            print("yeah!")
        }
    }
}

这篇关于Swift协议要求只能通过使用最终的类来满足的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆