代码之家  ›  专栏  ›  技术社区  ›  Jeremy Rajan Balana

返回符合常规约束的对象

  •  0
  • Jeremy Rajan Balana  · 技术社区  · 7 年前

    我正在尝试创建一个 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 ,但我希望能够隐藏实现细节。我错过了什么?

    0 回复  |  直到 7 年前
        1
  •  1
  •   Alexander    7 年前

    我不知道如何解决这个问题,但问题的根源在于 newBuilder(someDependancy:) 具有泛型类型签名,但它实际上不是泛型的。

    其返回类型断言函数可以返回任何类型的对象 T: BuilderType where Builder.ObjectType == O ,但情况显然并非如此。要求此函数返回除 ConcreteBuilder let myBuilder: MyBuilder = ComplexObject.newBuilder(someDependancy: dec) ,代码将崩溃(即使 MyBuilder 满足您的常规约束),因为您试图强制强制强制转换 到 MyBuilder

    就解决方案而言。。。我没有。基本上你只想回来 BuilderType

        2
  •  0
  •   Durdu    7 年前

    这样行吗?

    return ConcreteBuilder(someDependency: someDependency) as! Builder