受其他泛型参数约束的泛型参数
Posted
技术标签:
【中文标题】受其他泛型参数约束的泛型参数【英文标题】:Generic parameter constrained by other generic parameter 【发布时间】:2015-05-23 21:50:05 【问题描述】:由于 Swift 缺乏协方差,我需要一些解决方法。我来自 Java 世界,所以我本能地尝试创建从一种类型到另一种泛型类型的约束。
所以我写了以下类:
class Factory<T: AnyObject>
let factoryClosure: () -> T
init(closure: () -> T)
factoryClosure = closure
init<CHILD: T>(childFactory: Factory<CHILD>)
factoryClosure = () -> T in
return otherFactory.create()
func create() -> T
return factoryClosure()
我希望这可以正常工作。我定义了T
,CHILD
应该是T
的子类。然而,Swift 编译器不同意并在init<CHILD: T>
行显示以下错误。
从非协议、非类类型'T'继承
我也尝试了不同场景下的泛型参数继承。将以下方法添加到类中(并删除导致编译错误的 init)。
func to<OTHER where OTHER: AnyObject, T: OTHER>()
这会产生基本相同的输出。
类型“T”被限制为非协议类型“OTHER”
任何我可能工作的东西都没有,并以类似的错误消息结束。这是 Swift 中的错误吗?还是我错过了什么?或者它是 Swift 的一个特性,永远不会像我想的那样工作?
【问题讨论】:
您真正想要实现的目标是什么?实际目标是,而不是一些试图实现所述未说明目标的代码。 我想要实现的目标是有一些东西可以让我解决缺少协方差的问题(如果我没记错的话)。在 Java 中,我将使用Factory<? extends MyObject>
并可以传入 Factory
的任何实例,该实例的类型参数为 MyObject
或其子项。
这听起来仍然是手段而不是目的。实际目标是什么?
对,对不起,我一开始没有找到你。目标是某种依赖注入。我想将依赖项作为初始化参数。实例本身或我可以稍后调用以获取实例的工厂。问题出在后者,因为当我有init(someFactory: Factory<Some>
时,我无法通过Factory<MockSome>
。
typhoonframework.org 是一个依赖注入框架
【参考方案1】:
如果你想传递任何Factory<T>
,其中T
的类型是AnyObject
,你只需要写:
init(childFactory: Factory<T>)
factoryClosure = () -> T in
return otherFactory.create()
因为 T 会自动受到您的类的约束。
【讨论】:
这不会解决问题,因为您只能传入Factory<T>
而不能传入Factory<Z>
,其中Z
是T
的子类。
我认为这解决了你的问题,因为如果Z
是T
的子类,它也是AnyObject
类型。因此您也可以传递Factory<Z>
(T
只是符合AnyObject
的类型的占位符)
在上下文中,T
已经受您正在创建的类的约束。因此,如果您这样做let zFactory = Factory<Z>() return Z() ; let tFactory = Factory<T>(childFactory: zFactory)
,它将无法正常工作。以上是关于受其他泛型参数约束的泛型参数的主要内容,如果未能解决你的问题,请参考以下文章