返回符合泛型约束的对象

问题描述 投票:0回答:2

我正在尝试为我的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,但我希望能够隐藏该实现细节。我在这里错过了什么?

swift generics swift-protocols
2个回答
1
投票

我不确定如何解决这个问题,但问题的根源是newBuilder(someDependancy:)有一个通用的类型签名,但它真的不是通用的。

它的返回类型声明函数可以返回任何类型的T: BuilderType where Builder.ObjectType == O对象,但事实并非如此。要求此函数返回除ConcreteBuilder之外的任何类型都不受支持。充其量,你可以使用强制转换,但如果有人写let myBuilder: MyBuilder = ComplexObject.newBuilder(someDependancy: dec),代码将崩溃(即使MyBuilder满足你的通用约束),因为你试图强制施放ConcreteBuilderMyBuilder

至于解决方案......我没有。从根本上说,你只想返回BuilderType,但我不认为这是可能的,因为它有一个相关的类型。


0
投票

这会吗?

return ConcreteBuilder(someDependency: someDependency) as! Builder
© www.soinside.com 2019 - 2024. All rights reserved.