我正在尝试实现 either
函数,它接受两个通用容器并返回其中一个:
func either<A,B>(a: Container<A>, b: Container<B>) -> ?either Container<A> or Container<B>? {
// choose any of container
return chosen
}
看起来我需要一个 Container 必须遵守的协议(protocol),这样我的 either
的返回类型应该是这个协议(protocol)。
这是正确的解决方案吗?
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
反而。我应该为原始选项添加另一个枚举吗?有什么想法吗?
最佳答案
传统的 Either
类型如下所示:
enum Either<A, B>
{
case Left(A)
case Right(B)
}
并且更有用,因为它不限于您的 Container
类型。
(Either
是“规范的”求和类型。)
它会像这样使用:
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)
}
}
关于swift - 返回两个泛型之一的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32668363/