使用Self作为通用类型

时间:2014-12-16 13:54:30

标签: generics swift

Self可用作方法的返回类型:

func doSomething() -> Self {}

以某种方式使用Self作为通用类型是否可行?

func doSomething() -> Wrapper<Self> {}

示例

如果我可以继承ChristmasPresent并让它有一个wrapped函数,它会返回带有泛型集的WrappedPresent,而不管子类是什么,这将是很好的。

class ChristmasPresent {
    func wrapped() -> WrappedPresent<Self> {
        return WrappedPresent(present: self)
    }
}

class WrappedPresent<T: ChristmasPresent> {
    var present: T

    init(present: T) {
        self.present = present
    }
}

class ToyCar: ChristmasPresent {}

let wrappedToyCar = ToyCar().wrapped() // Inferred to be: WrappedPresent<ToyCar> 

1 个答案:

答案 0 :(得分:21)

Swift中最令人烦恼的悖论是:&#34; Swift更喜欢方法,但Swift的功能更强大。&#34; Swift团队知道这一点,总有一天我确信我们会有强大的方法。但今天不是那一天。你想用方法表达的东西很多,你不能。但是,你想要的一切都可以通过功能轻松完成。

class ChristmasPresent {}

struct WrappedPresent<T: ChristmasPresent> {
    let present: T
}

func wrap<T:ChristmasPresent>(present: T) -> WrappedPresent<T> {
    return WrappedPresent(present: present);
}

class ToyCar: ChristmasPresent {}

let wrappedToyCar = wrap(ToyCar()) // Inferred to be: WrappedPresent<ToyCar>

请注意,如果您的代码已经编译,您可能会对结果感到非常惊讶。 Swift custom types are not covariant,因此WrappedPresent<ToyCar>不是WrappedPresent<ChristmasPresent>的子类型。因此,如果您有一系列包裹的礼物,您就无法将包裹的toycar放入其中。这可能很容易迫使你回到仅使用固定(非类型参数化)WrappedPresent类型,使问题没有实际意义。泛型和类并不总是像你在Swift中想象的那样混合。

如果你有一个问题的实际例子,你想用这个来解决,那么我建议你在开发论坛上提出它。 Swift团队非常敏感。