返回两个泛型中的任何一个的函数

时间:2015-09-19 12:44:29

标签: swift generics swift2

我正在尝试实现echo "<td><img src='".$image."'></td>"; 函数,该函数接受两个通用容器并返回其中任何一个:

either

看起来我需要一个容器必须符合的协议,这样我的func either<A,B>(a: Container<A>, b: Container<B>) -> ?either Container<A> or Container<B>? { // choose any of container return chosen } 的返回类型应该是这个协议。 这是正确的解决方案吗?

either

更新

好的,所以我已经实现了EitherContainer枚举,最终的代码如下:

protocol ContainerProtocol
struct Container<T>: ContainerProtocol

func either<A: ContainerProtocol, B:ContainerProtocol, C:ContainerProtocol>(a: A, b: B) -> C {
    // choose any of container
    return chosen
}
现在困扰我的是struct Container<T>: Unique { typealias UnderlyingObject = T var object: UnderlyingObject var uniqueId: String } enum EitherContainer<A,B> { case a(container: Container<A>) case b(container: Container<B>) } func wrappedInput<A,B>(wra: Container<A>, wrb: Container<B>, paramClosure: (Container<A>, Container<B>) -> EitherContainer<A,B>) -> EitherContainer<A,B> { //do some work here return paramClosure(wra, wrb) } func rawInput<A, B>(a: A, b: B) -> Any { let wrappedA = Container(object: a, uniqueId: "a") let wrappedB = Container(object: b, uniqueId: "b") let wrappedRes = wrappedInput(wrappedA, wrb: wrappedB) { (a1: Container, a2: Container) -> EitherContainer<A,B> in // do some work here return EitherContainer.a(container: a1) } var rawRes: Any switch wrappedRes { case .a(let container): rawRes = container.object case .b(let container): rawRes = container.object } return rawRes } 类型,它关闭了编译器,但对我来说看起来像一个弱的拐杖。同样的问题AnyrawInput<A, B>(a: A, b: B) -> Any应返回A或B,但我不得不使用rawInput。我应该为原始选项添加另一个枚举吗?有什么想法吗?

1 个答案:

答案 0 :(得分:3)

传统的Either类型如下所示:

enum Either<A, B>
{
    case Left(A)
    case Right(B)
}

并且更有用,因为它不仅限于您的Container类型 (Either是&#34;规范&#34;和类型。)

它会像这样使用:

func wrappedInput<A, B> (
    a : Container<A>,
    b: Container<B>,
    paramClosure: (Container<A>, Container<B>) -> Either<Container<A>,Container<B>>
    ) -> Either<Container<A>, Container<B>>
{
    return Either.Left(a) // Dummy
}

func rawInput<A, B>(a: A, b: B) -> Either<A,B> {
    let wrappedA = Container(object: a, uniqueId: "a")
    let wrappedB = Container(object: b, uniqueId: "b")
    let wrappedRes = wrappedInput(wrappedA, b: wrappedB) {
        (a1: Container, a2: Container) -> Either<Container<A>, Container<B>> in
        // do some work here
        return Either.Left(a1)
    }

    switch wrappedRes {
    case .Left(let container):
        return Either.Left(container.object)
    case .Right(let container):
        return Either.Right(container.object)
    }
}