为什么`required`不是Swift中类函数的有效关键字?

时间:2014-09-19 12:18:47

标签: swift

似乎在某些情况下,Swift类函数上的required关键字非常有用,特别是由于类函数返回Self的能力。

Self返回class func时,不幸的是有两个限制使得实现所述功能非常困难/具有抑制性:

  1. 您不能在函数实现中使用Self作为类型检查,即:

    class Donut {
        class func gimmeOne() -> Self {
            // Compiler error, 'Self' is only available in a protocol or as the result of a class method
            return Donut() as Self
        }
    }
    
  2. 您无法返回类本身的实际类型,即:

    class Donut {
        class func gimmeOne() -> Self {
            // Compiler error, 'Donut' is not convertible to 'Self'
            return Donut() 
        }
    }
    
  3. 这些编译器错误的原因有效。如果您的GlazedDonut子类没有覆盖此类函数,则调用GlazedDonut.gimmeOne()可能会返回Donut,其中不是 a Self

    似乎这种情况可以通过允许类使用required指定这些函数来缓解。这将确保任何子类重写该方法并进行自己的类型检查,确保GlazedDonut在所有情况下都返回自身,从而消除Donut返回的可能性。

    是否存在技术,权威的原因尚未添加?我想建议它是Swift团队的一项改进,但是要确保没有明显的原因导致它被忽略或无法完成。

    这个问题的想法源于此:

    https://stackoverflow.com/a/25924224/88111

2 个答案:

答案 0 :(得分:1)

您可以使用协议使方法“必需”

protocol IDonut{
    class func gimmeOne()->Donut;
}

class Donut:IDonut {
    class func gimmeOne() -> Donut {
        return Donut();
    }
}

class GlazedDonut: Donut, IDonut{
    override class func gimmeOne()->Donut{
        return GlazedDonut();
    }
}

答案 1 :(得分:1)

required通常仅用于初始化程序,因为初始化程序并不总是在Swift中继承。因此,为了允许您在变量类上调用初始值设定项(即元类类型的值,比如Foo.Type),您需要知道该类Foo以及所有可能的子类都具有此初始值设定项

但是,方法(实例方法和类方法)始终是继承的。因此,required不是必需的。

顺便说一句,你的断言是"你无法返回班级本身的实际类型"不是真的。 (实际上,错误"' Self'只能在协议中使用,或者作为类方法的结果"本身表示您可以返回类本身的类型。)类似于在Objective-C中,你可以这样做:

class Donut {
  required init() { }
  class func gimmeOne() -> Self {
    return self()
  }
}