协议函数返回自

协议函数返回自

我有一个协议P,它返回对象的副本:

protocol P {
    func copy() -> Self}

以及实现P的类C:

class C : P {
    func copy() -> Self {
        return C()
    }}

但是,是否将返回值作为Self我得到以下错误:

无法将“C”类型的返回表达式转换为返回类型“Self”

我也试着回去C.

class C : P {
    func copy() -> C  {
        return C()
    }}

这导致以下错误:

非终级“C”中的方法“Copy()”必须返回Self遵守“P”协议

除了我前缀的情况外,什么都不起作用。class C带着final(如:

final class C : P {
    func copy() -> C  {
        return C()
    }}

但是,如果我想要子类C,那么什么都不能工作。有办法绕过这件事吗?


偶然的你
浏览 375回答 3
3回答

Cats萌萌

问题是,您正在做出编译器无法证明您将遵守的承诺。所以你创造了这样的承诺:copy()将返回自己的类型,完全初始化。但是你实现了copy()这样:func copy() -> Self {     return C()}现在我是一个不覆盖的子类copy()..我还给你一个C,而不是完全初始化Self(这是我答应过的)。所以这样不好。不如:func copy() -> Self {     return Self()}嗯,这不会编译,但即使编译了,也是没有好处的。子类可能没有简单的构造函数,因此D()甚至可能是不合法的。(尽管见下文)好吧,那么:func copy() -> C {     return C()}是的,但那不会回来Self..它回来了C..你还是没信守诺言。“但是objc可以做到!”算是吧。主要是因为它不在乎你是否像斯威夫特那样信守诺言。如果你不能实现copyWithZone:在子类中,可能无法完全初始化对象。编译器甚至不会警告您已经这样做了。“但是objc中的大多数东西都可以翻译成SWIFT,而objc有NSCopying“是的,它是这样定义的:func copy() -> AnyObject!所以你可以做同样的(没有理由!)在此):protocol Copyable {   func copy() -> AnyObject}上面写着“我不会保证你会得到什么。”你也可以说:protocol Copyable {   func copy() -> Copyable}这是你可以做出的承诺。但是我们可以考虑一下C+,记住我们有一个承诺能,会,可以制作,使。我们可以保证,我们和所有子类都将实现特定类型的初始化器,SWIFT将强制执行这一点(因此可以证明我们说的是实话):protocol Copyable {   init(copy: Self)}class C : Copyable {   required init(copy: C) {     // Perform your copying here.  }}这就是你应该做的拷贝。我们可以更进一步,但是dynamicType,我还没有对它进行广泛的测试,以确保这始终是我们想要的,但它应该是正确的:protocol Copyable {   func copy() -> Self   init(copy: Self)}class C : Copyable {   func copy() -> Self {     return self.dynamicType(copy: self)   }   required init(copy: C) {     // Perform your copying here.  }}在这里,我们保证有一个初始化程序为我们执行副本,然后我们可以在运行时确定要调用哪一个,给出您要寻找的方法语法。

MMTTMM

使用SWIFT 2,我们可以使用协议扩展。protocol Copyable {     init(copy:Self)}extension Copyable {     func copy() -> Self {         return Self.init(copy: self)     }}

胡说叔叔

还有一种方法可以实现你想做的事情,那就是利用SWIFT的关联类型。下面是一个简单的例子:public protocol Creatable {     associatedtype ObjectType = Self     static func create() -> ObjectType}class MyClass {     // Your class stuff here}extension MyClass: Creatable {     // Define the protocol function to return class type    static func create() -> MyClass {          // Create an instance of your class however you want        return MyClass()     }}let obj = MyClass.create()
打开App,查看更多内容
随时随地看视频慕课网APP