Generics Swift从泛型类型继承

Generics Swift从泛型类型继承,generics,swift,Generics,Swift,我试图从泛型类型继承,以便可以将类型插入层次结构: class Foo < T:AnyObject > : T {} 但我要确保T是一个类(即使我将任何对象更改为其他类)。这是不可能的吗?如果你不知道某个东西是什么,出于多种原因,你就不能继承它 首先,编译器需要知道如何在内存中布局类的实例。为此,它需要知道它有哪些实例变量(存储的属性):类指定的变量和从超类继承的变量 编译器还需要了解超类的属性和初始值设定项,以确保类的实例已正确初始化。如果超类的属性未知,则无法知道您是否已在初

我试图从泛型类型继承,以便可以将类型插入层次结构:

class Foo < T:AnyObject > : T {}

但我要确保T是一个类(即使我将任何对象更改为其他类)。这是不可能的吗?

如果你不知道某个东西是什么,出于多种原因,你就不能继承它

  • 首先,编译器需要知道如何在内存中布局类的实例。为此,它需要知道它有哪些实例变量(存储的属性):类指定的变量和从超类继承的变量

  • 编译器还需要了解超类的属性和初始值设定项,以确保类的实例已正确初始化。如果超类的属性未知,则无法知道您是否已在初始值设定项结束之前初始化了所有应该(以及不应该)的状态。如果超类的初始值设定项未知,编译器无法强制您从自己的初始值设定项调用超类的指定初始值设定项

  • 如果不知道超类是什么,您将如何编写引用超类的属性和方法的方法实现?如果您编写的代码引用了
    self.view
    ,然后以某种方式实例化一个不从具有该属性的类继承的类的版本,则该代码将中断

可能还有几个原因,但这些应该足够了

虽然有一些地方需要子类化,但Cocoa(无论是在Swift还是ObjC中)通常倾向于使用继承而不是自定义

如果要向各种视图控制器添加一组功能,并通过将代码分解为自己的类来重用代码,那么简单的解决方案是让视图控制器类都拥有该类的实例,而不是试图成为该类的实例。如果您想强制某些视图控制器类必须拥有
Foo
,则可以定义一个表示该要求的协议

如果您试图向现有类添加功能,则可以使用扩展。您可能无法使用扩展来添加存储属性,但您肯定可以伪造它。例如,您可以使用计算属性,并在其实现中定义自己的存储。实现这一点的一种方法可能是使用ObjC运行时(AFAIK仍然可以从Swift访问该运行时)。

CRTP()是否与OP中的有所不同


用Swift设计这种图案完全可以(是的,您不能从泛型的子类型继承。您可以使用装饰器模式而不是继承来做您想要做的事情吗?我想做的是更改从NSViewController继承的类,使其从Foo继承,Foo反过来又从NSViewController继承,但将来如果我想从其他c继承,还可以使用Foo。)Foo有成员变量,所以我不能使用扩展,我也不确定如何使用decoratorSwift来支持这种奇怪的重复模板模式()对于C++、java和.net来说,这可能是因为它不使用调用站点类型推断,虽然我不知道java和.NET是否是真的,因此它是实际的限制。虽然它是一个很好的有用的特性。我在这个论坛上发布了一个关于这个主题的问题:我不同意原因:T的类型在编译时是已知的。在提姆对于派生类的实例化,编译器需要知道所有必需的类型。在C++中,这是一种常见的模式,没有涉及到动态类型。例如,TBF
T
不知道该库代码是否存在。但是,如果类必须在范围内最多为
内部
,则可以避免这种情况。问题不在于CRTP。
inheritance from non-protocol, non-class type 'T'
class Template<T> { ... }

class RealThing : Template<RealThing> { ... }
protocol Constructor {
    init()
}

protocol Shape {
    func cloned() -> Shape
}

typealias ShapeProtocols = Constructor & Shape

class Shape_CRTP<T> : ShapeProtocols {

    required init() {}

    func  cloned() -> Shape {
        let new = Shape_CRTP<T>()
        // copy everything to `new` from `self`
        return new
    }
}

extension Shape_CRTP where T : ShapeProtocols {

    func cloned() -> Shape {
        let new = T()
        // copy everything to `new` from `self`
        return new
    }
}

// First non-crtp proof of concept
class Square : ShapeProtocols {

    required init() {}
    func cloned() -> Shape {
        return Square()
    }
}

let clone = Shape_CRTP<Square>().cloned() // creates a new `Shape`
type(of: clone) // Square.Type

// now CRTP but this is bugged: http://blog.devandartist.com/posts/swift-crtp
class Circle : Shape_CRTP<Circle> {}

Circle().cloned()

print("this will never print because of the described bug")