我正在尝试为我的Builder
创建一个ComplexObject
:
import Foundation
class ComplexObject {
// lots of stuff
init<ObjectType, T>(_ closure: ((ObjectType) -> T)) {
// lots of init/setup code
}
// other initializers with generics, constructed
// by other Builders than ConcreteBuilder<O> below
}
protocol BuilderType {
associatedtype ObjectType
func title(_: String) -> Self
func build<T>(_ closure: ((ObjectType) -> T)) -> ComplexObject
}
struct Injected<O> {
//...
}
extension ComplexObject {
static func newBuilder<Builder: BuilderType, O>(someDependency: Injected<O>) -> Builder where Builder.ObjectType == O {
// vvvv
return ConcreteBuilder(someDependency: someDependency)
// ^^^^
// Cannot convert return expression of type 'ComplexObject.ConcreteBuilder<O>' to return type 'Builder'
}
struct ConcreteBuilder<O>: BuilderType {
private let dependency: Injected<O>
private var title: String
init(someDependency: Injected<O>) {
self.dependency = someDependency
}
func title(_ title: String) -> ConcreteBuilder<O> {
var builder = self
builder.title = title
return builder
}
func build<T>(_ closure: ((O) -> T)) -> ComplexObject {
return ComplexObject(closure)
}
}
}
但swiftc
抱怨return ConcreteBuilder(...)
线
Cannot convert return expression of type 'ComplexObject.ConcreteBuilder<O>' to return type 'Builder'
我也试过了
static func newBuilder<Builder: BuilderType>(someDependency: Injected<Builder.ObjectType>) -> Builder {
return ConcreteBuilder(someDependency: someDependency)
}
结果相同。我看到我可以公开ConcreteBuilder
,但我希望能够隐藏该实现细节。我在这里错过了什么?
我不确定如何解决这个问题,但问题的根源是newBuilder(someDependancy:)
有一个通用的类型签名,但它真的不是通用的。
它的返回类型声明函数可以返回任何类型的T: BuilderType where Builder.ObjectType == O
对象,但事实并非如此。要求此函数返回除ConcreteBuilder
之外的任何类型都不受支持。充其量,你可以使用强制转换,但如果有人写let myBuilder: MyBuilder = ComplexObject.newBuilder(someDependancy: dec)
,代码将崩溃(即使MyBuilder
满足你的通用约束),因为你试图强制施放ConcreteBuilder
到MyBuilder
。
至于解决方案......我没有。从根本上说,你只想返回BuilderType
,但我不认为这是可能的,因为它有一个相关的类型。
这会吗?
return ConcreteBuilder(someDependency: someDependency) as! Builder