【发布时间】:2015-09-19 12:44:28
【问题描述】:
我正在尝试实现either 函数,它接受两个通用容器并返回其中一个:
func either<A,B>(a: Container<A>, b: Container<B>) -> ?either Container<A> or Container<B>? {
// choose any of container
return chosen
}
看起来我需要一个协议,容器必须遵守,所以我的either 的返回类型应该是这个协议。
这是正确的解决方案吗?
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
}
更新
好的,我已经实现了 EitherContainer 枚举,最终代码如下:
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
}
现在困扰我的是Any 类型,它会关闭编译器,但对我来说看起来像是一个弱拐杖。同样的问题rawInput<A, B>(a: A, b: B) -> Any。 rawInput 应该返回 A 或 B,但我不得不改用 Any。我应该为原始选项添加另一个枚举吗?有什么想法吗?
【问题讨论】:
-
您的解决方案绝对有效。另一种方法是实现
enum Either<A, B>类型,其中两种情况对应于每种可能性。然后您可以在返回值上switch并获取选择的容器。这样你的类型信息就不会通过函数丢失。 -
@Peter 是的,枚举解决方案非常简洁