符合通用协议方法返回 PAT
Conforming to generic protocol method returning PATs
我想声明类似于以下的通用协议:
protocol Factory {
func createWidget<T, TWidget>(_ t: T) -> TWidget
where TWidget: Widget, TWidget.T == T
}
protocol Widget {
associatedtype T
func get() -> T
}
我希望我可以实现 Factory
的具体变体 return 使用隐藏的实现来实现他们自己的具体和不透明 Widget
。
这是一个构建失败的示例实现:
struct ConcreteFactory: Factory {
func createWidget<T, TWidget>(_ t: T) -> TWidget
where TWidget: Widget, TWidget.T == T {
// This line has an error…
return ConcreteWidget(widgetValue: t)
}
}
struct ConcreteWidget<T>: Widget {
let widgetValue: T
init(widgetValue: T) {
self.widgetValue = widgetValue
}
func get() -> T {
return widgetValue
}
}
但是,这不会编译。
在指定的行,Swift 的编译器给出错误 "Cannot convert return expression of type 'ConcreteWidget' to return type 'TWidget'"。
我也试过 ConcreteFactory
return 一个 ConcreteWidget
,但是错误是 ConcreteFactory
不符合 Factory
.
这不行。当您 调用 您的 createWidget
方法时,您指定了两种类型 T
和 TWidget
.
struct MyWidget: Widget {
func get() -> Int { ... }
}
let widget: MyWidget = factory.createWidget(12)
在此示例中,TWidget
是 MyWidget
,T
是 Int
。这很好地说明了为什么您的方法行不通。您不能将 ConcreteWidget<Int>
分配给 MyWidget
.
类型的变量
您需要的是 类型橡皮擦 用于您的小部件。目前您必须自己编写,但将来编译器有望在需要时自动生成它们。
struct AnyWidget<T>: Widget {
private let _get: () -> T
init<Other: Widget>(_ other: Other) where Other.T == T {
_get = other.get
}
func get() -> T {
return _get()
}
}
这允许您编写工厂协议和实现:
protocol Factory {
func createWidget<T>(_ t: T) -> AnyWidget<T>
}
struct ConcreteFactory: Factory {
func createWidget<T>(_ t: T) -> AnyWidget<T> {
return AnyWidget(ConcreteWidget(widgetValue: t))
}
}
我想声明类似于以下的通用协议:
protocol Factory {
func createWidget<T, TWidget>(_ t: T) -> TWidget
where TWidget: Widget, TWidget.T == T
}
protocol Widget {
associatedtype T
func get() -> T
}
我希望我可以实现 Factory
的具体变体 return 使用隐藏的实现来实现他们自己的具体和不透明 Widget
。
这是一个构建失败的示例实现:
struct ConcreteFactory: Factory {
func createWidget<T, TWidget>(_ t: T) -> TWidget
where TWidget: Widget, TWidget.T == T {
// This line has an error…
return ConcreteWidget(widgetValue: t)
}
}
struct ConcreteWidget<T>: Widget {
let widgetValue: T
init(widgetValue: T) {
self.widgetValue = widgetValue
}
func get() -> T {
return widgetValue
}
}
但是,这不会编译。
在指定的行,Swift 的编译器给出错误 "Cannot convert return expression of type 'ConcreteWidget' to return type 'TWidget'"。
我也试过 ConcreteFactory
return 一个 ConcreteWidget
,但是错误是 ConcreteFactory
不符合 Factory
.
这不行。当您 调用 您的 createWidget
方法时,您指定了两种类型 T
和 TWidget
.
struct MyWidget: Widget {
func get() -> Int { ... }
}
let widget: MyWidget = factory.createWidget(12)
在此示例中,TWidget
是 MyWidget
,T
是 Int
。这很好地说明了为什么您的方法行不通。您不能将 ConcreteWidget<Int>
分配给 MyWidget
.
您需要的是 类型橡皮擦 用于您的小部件。目前您必须自己编写,但将来编译器有望在需要时自动生成它们。
struct AnyWidget<T>: Widget {
private let _get: () -> T
init<Other: Widget>(_ other: Other) where Other.T == T {
_get = other.get
}
func get() -> T {
return _get()
}
}
这允许您编写工厂协议和实现:
protocol Factory {
func createWidget<T>(_ t: T) -> AnyWidget<T>
}
struct ConcreteFactory: Factory {
func createWidget<T>(_ t: T) -> AnyWidget<T> {
return AnyWidget(ConcreteWidget(widgetValue: t))
}
}