[swift-users] Generics with variable argument lists

Ole Begemann ole at oleb.net
Thu Mar 9 05:36:44 CST 2017


On 09/03/2017 11:05, Rien via swift-users wrote:
> I am trying to achieve the following:
>
> enum FunctionResult<T> {
>   case success(T)
>   case error(String)
> }
>
> func tester<T>(test: (…) -> FunctionResult<T>, onError: (String) -> T) -> T {
>> }
>
> The problem is of course the (…) that simply does not work.
>
> I would like to use this generic with a variety of different signatures, i.e.:
>
> let result1 = tester(test: myfunc1(param: 26) -> FunctionResult<Bool>, onError: { … handle the error ... })
> let result2 = tester(test: myfunc2(param: “A String") -> FunctionResult<Bool>, onError: { … handle the error ... })
> let result3 = tester(test: myfunc3(param: 26, param2: “String") -> FunctionResult<Int>, onError: { … handle the error ... })
>
> Is this at all possible?

This should do it:

     func tester<T>(test: @autoclosure () -> FunctionResult<T>,
         onError: (String) -> T) -> T {
         switch test() {
         case .success(let value): return value
         case .error(let error): return onError(error)
         }
     }

The insight is that you don't really want to pass a function in the 
first parameter, but only the _result_ of that function call. The 
@autoclosure attribute then makes sure that the expression you pass to 
tester is only evaluated inside tester. You can leave it out if you want 
(if you do, replace `switch test()` with `switch test`).



More information about the swift-users mailing list