Я пытаюсь реализовать 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
}
UPDATE
нормально, так что я реализовал 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
. Должен ли я добавить еще одно перечисление для необработанных параметров? Есть предположения?
Ваше решение, безусловно, работает. Другим подходом является реализация типа «перечисление Либо » с двумя случаями, соответствующими каждой возможности. Затем вы можете «переключиться» на возвращаемое значение и получить выбранный контейнер. Таким образом, ваша информация о типе не будет потеряна через эту функцию. –
@Peter yea, enum solution довольно аккуратно –