Jes*_*ssy 5 inheritance protocols swift
错误:协议'协议'要求'实例'不能被非最终类('Class')满足,因为它在非参数非结果类型位置使用'Self'
protocol Protocol {
var instance: Self {get}
}
class Class: Protocol {
var instance: Class {return Subclass()}
}
class Subclass: Class {}
Run Code Online (Sandbox Code Playgroud)
以下是我在C#中表达我想要的内容.(据我所知,C#没有办法强制通用参数"Self"实际上是我们从Swift中知道的Self,但它的功能很好,因为文档可以让我做正确的事.)
interface Protocol<Self> where Self: Protocol<Self> {
Self instance {get;}
}
class Class: Protocol<Class> {
public Class instance {get {return new Subclass();}}
}
class Subclass: Class {}
Run Code Online (Sandbox Code Playgroud)
...在未来版本的Swift中看起来如何:
protocol Protocol {
typealias FinalSelf: Protocol where FinalSelf.FinalSelf == FinalSelf
var instance: FinalSelf {get}
}
class Class: Protocol {
var instance: Class {return Subclass()}
}
class Subclass: Class {}
Run Code Online (Sandbox Code Playgroud)
我是如何模仿与我的问题相关的部分:
protocol Protocol: ProtocolInstance {
static var instance: ProtocolInstance {get}
}
protocol ProtocolInstance {}
class Class: Protocol {
static var instance: ProtocolInstance {return Subclass()}
}
class Subclass: Class {}
Run Code Online (Sandbox Code Playgroud)
而且,我认为这是我的代码的相关部分:
protocol Protocol {
static var : Self? {get} // an existing instance?
static var : Self {get} // a new instance
func instanceFunc()
}
extension Protocol {
static func staticFunc() {
( ?? ).instanceFunc()
}
}
Run Code Online (Sandbox Code Playgroud)
正如它所说,你不能这样做,并且有充分的理由.你不能证明你会信守诺言.考虑一下:
class AnotherSubclass: Class {}
let x = AnotherSubclass().instance
Run Code Online (Sandbox Code Playgroud)
所以x应该AnotherSubclass根据你的协议(那是Self).但它实际上是Subclass,这是一种完全不同的类型.除非上课,否则你无法解决这个悖论final.这不是斯威夫特的限制.这种限制将存在于任何正确的类型系统中,因为它允许类型矛盾.
另一方面,你可以做的是承诺instance在所有子类(即超类)中返回一些一致的类型.您可以使用关联类型执行此操作:
protocol Protocol {
typealias InstanceType
var instance: InstanceType {get}
}
class Class: Protocol {
var instance: Class {return Subclass()}
}
class Subclass: Class {}
class AnotherSubclass: Class {}
let x = AnotherSubclass().instance
Run Code Online (Sandbox Code Playgroud)
现在x是明确的类型Class.(它也恰好是随机的其他子类,这有点奇怪,但这就是代码所说的.)
顺便说一句,所有这些通常都表明你正在使用子类化,而你真的不应该这样做.组合和协议可能会更好地解决Swift中的这个问题.问问自己是否有任何理由Subclass需要实际上是一个子类Class.它是一个符合相同协议的独立类型吗?当你摆脱子类并专注于协议时,各种问题都会消失.
我一直在考虑这个问题,并且可能有办法获得你想要的东西.而不是说所有子类都实现instance,instance作为扩展附加.如果要返回其他内容,仍然可以覆盖它.
protocol Protocol {
init()
}
class Class: Protocol {
required init() {}
var instance: Class { return Subclass() }
}
extension Protocol {
var instance: Self { return self.dynamicType.init() }
}
class Subclass: Class {}
Run Code Online (Sandbox Code Playgroud)
这避免了继承问题(你不能以AnotherClass这种方式创建相同的" 返回错误的类型").