使用swift中泛型类派生的类的限制

ssg*_*reg 34 generics class swift

我试图从泛型类派生我的类:

class foo<T> {}
class bar : foo<Int> {}
Run Code Online (Sandbox Code Playgroud)

但是此代码无法使用en错误进行编译:

从泛型类派生的类也必须是通用的

如何避免这种限制?可能吗?

Jea*_*nan 23

Ssreg,

不幸的是这是正式的:

您可以子类化泛型类,但子类也必须是泛型类.

让我们希望Apple在未来版本中修复此问题.

同时,让我们将此视为利用聚合而非子类化的机会.

注意:

作为穷人的解决方案版本,可以使用typealias:

class foo<T> {}
class bar<Int> : foo<Int> {}
typealias Bar = bar<Int>
Run Code Online (Sandbox Code Playgroud)

这样,其余的代码就可以像Apple已经解决了这个问题一样编写.

  • 让我们注意,当你编写`class bar <Int>:foo <Int> {}时,Int成为泛型类型的占位符,覆盖实际的swift Int类型.当您尝试在类中使用Int的属性时,这将生成非常有趣的错误消息.最好在子类中使用未使用的泛型类型的hpique解决方案,并将基类绑定到实际的Int类型(或者期望的一个) (4认同)

Tom*_*ren 17

我有同样的问题,我找到了解决方案!

class SomeType {
}
class Foo<T> {
}
class Bar<T: SomeType>: Foo<T> {
}
Run Code Online (Sandbox Code Playgroud)

现在你可以这样做:

let bar = Bar()
Run Code Online (Sandbox Code Playgroud)

这将默认Bar的类型设置为SomeType.唯一的缺点是你只能为'subclassable'类型执行此操作.因此,Int这不起作用.


ric*_*ira 16

在Swift 2中,可以将泛型类子类化:

class Something {}

class Base<T> {}

class Fancy : Base<Something> {}
Run Code Online (Sandbox Code Playgroud)


hpi*_*que 15

typealias 解决方案的替代方案是按字面意思获取文档:

您可以子类化泛型类,但子类也必须是泛型类.

因此,我们将子类设为泛型类,但是我们不使用任何其他类型.

class foo<T> {

    func doSomething(t:T) -> T {
        return t;
    }
}

class bar<S> : foo<Int> {

    override func doSomething(t:Int) -> Int {
        return t * t;
    }
}

let b : bar = bar<AnyObject>()
b.doSomething(5) // 25 instead of 5
Run Code Online (Sandbox Code Playgroud)

我更喜欢使用这种方法,typealias因为它不会使用其他类型污染命名空间.如果子类(bar)意味着public或是,那么这一点尤为重要internal.

编辑

该文档不再包含有关泛型子类限制的短语.希望这意味着Apple计划尽快改变这一点.