1

Consider this code:

func testA(){}
func testB(value:Int){}
func testC(value:String){}

var someTest:Any = testA

How do you case-match on a variable holding a closure to find the correct one so you can call it?

switch someTest{
    case let test where test:() -> Void:
        test()
    case let test where test:(value:Int) -> Void:
        test(4)
    case let test where test:(value:String) -> Void:
        test("A")
}

Is something like this possible?

Hamish
  • 78,605
  • 19
  • 187
  • 280
Mark A. Donohoe
  • 28,442
  • 25
  • 137
  • 286
  • 2
    You want e.g `case let test as (String) -> Void`, compare https://stackoverflow.com/q/38980403/2976878 – Hamish Mar 11 '18 at 17:22
  • 2
    Though depending on your use case, you may want to consider using an `enum` with associated values for each function type; then you can exhaustively switch without having to type-cast. – Hamish Mar 11 '18 at 17:24
  • @Alexander: That Q&A does not cover matching against closures, I wonder if this is worth a separate answer (preferably from Hamish due to his initial comment) – Martin R Mar 11 '18 at 18:13
  • Duh! as not where. Of course! Hamish, post that as an answer and I’ll accept it. – Mark A. Donohoe Mar 11 '18 at 18:51
  • @MarqueR IDK. Closures are such well-integrated types in the type system that I didn't (personally) expect them to be an exception in this case. Perhaps others would find it surprising – Alexander Mar 11 '18 at 20:16
  • @Alexander, I think you messed up our names. It was 'MartinR', not 'MarqueR'. Also, I agree with him in that this should probably not be marked as a duplicate. While closures are types as you correctly pointed out, they sometimes tend to still be thought of differently even though they aren't. For instance, I just made that very mistake that seems obvious in hindsight. – Mark A. Donohoe Mar 11 '18 at 20:24
  • 1
    Haha yes I did, and fair enough, i'll reopen – Alexander Mar 11 '18 at 20:28

1 Answers1

1

Closure types are subject to the same switching patterns that any other types are:

switch someClosure {
    case let runnable as () -> Void:
        runnable()
    case let intConsumer as (Int) -> Void:
        intConsumer(4)
    case let stringConsumer as (String) -> Void:
        stringConsumer("A")
}
Mark A. Donohoe
  • 28,442
  • 25
  • 137
  • 286
Alexander
  • 59,041
  • 12
  • 98
  • 151