classSuccessContainer<T>{init(t:T){// ...}}classErrorContainer<T>{init(t:T){// ...}}enumAPIResponse<JsonType,ErrorMsgType>{caseSuccess(SuccessContainer<JsonType>)caseFail(ErrorContainer<ErrorMsgType>)}// usagefuncGenAPIResponseSuccess<JsonType,ErrorMsgType>(json:JsonType)->APIResponse<JsonType,ErrorMsgType>{return.Success(SuccessContainer<JsonType>(t:json))}funcGenAPIResponseFail<JsonType,ErrorMsgType>(errorMsg:ErrorMsgType)->APIResponse<JsonType,ErrorMsgType>{return.Fail(ErrorContainer<ErrorMsgType>(t:errorMsg))}funccallbackFromAPI(response:String)->APIResponse<String,String>{if(response.hasPrefix("success")){returnGenAPIResponseSuccess(response)// can be parsed to json}else{returnGenAPIResponseFail(response)// just a plain error msg}}callbackFromAPI("success. I'm Json")callbackFromAPI("404 or something else")
But it is awful to write bunch of code for creating container classes, for each type you need.
publicfinalclassBox<T>:BoxType,Printable{/// Initializes a `Box` with the given value.publicinit(_value:T){self.value=value}/// Constructs a `Box` with the given `value`.publicclassfuncunit(value:T)->Box<T>{returnBox(value)}/// The (immutable) value wrapped by the receiver.publicletvalue:T/// Constructs a new Box by transforming `value` by `f`.publicfuncmap<U>(@noescapef:T->U)->Box<U>{returnBox<U>(f(value))}// MARK: Printablepublicvardescription:String{returntoString(value)}}
Finally
We can rewrite above code into this. Much more elegant.
1234567891011121314151617181920212223
enumAPIResponse2<JsonType,ErrorMsgType>{caseSuccess(Box<JsonType>)caseFail(Box<ErrorMsgType>)}funcGenAPIResponseSuccess2<JsonType,ErrorMsgType>(json:JsonType)->APIResponse2<JsonType,ErrorMsgType>{return.Success(Box<JsonType>(json))}funcGenAPIResponseFail2<JsonType,ErrorMsgType>(errorMsg:ErrorMsgType)->APIResponse2<JsonType,ErrorMsgType>{return.Fail(Box<ErrorMsgType>(errorMsg))}funccallbackFromAPI2(response:String)->APIResponse2<String,String>{if(response.hasPrefix("success")){returnGenAPIResponseSuccess2(response)// can be parsed to json}else{returnGenAPIResponseFail2(response)// just a plain error msg}}callbackFromAPI2("success. I'm Json")callbackFromAPI2("404 or something else")