2

I have been migrating my project code to Swift 4.0.

I am facing an issue with closures. In the below code snippet:

class ViewController: UIViewController
{    
    var completionClosure: ((Void)->(Void))? //WARNING: When calling this function in Swift 4 or later, you must pass a '()' tuple; did you mean for the input type to be '()'?

    override func viewDidLoad()
    {
        super.viewDidLoad()

        self.completionClosure = { //ERROR: Cannot assign value of type '() -> ()' to type '((Void) -> (Void))?'
            print("This is a closure.")
        }
    }
}

The above code worked perfectly in Swift 3.2. And in Swift 4.0, it is giving me these warnings and errors.

I understand there is no point in using Void if the closure doesn't contain any input arguments and return type, i.e the closure could have been written like:

var completionClosure: (()->())?

But still, why is it giving me the error? Isn't Void same as No Value?

Are there any changes introduced in the concept of closures since Swift 4.0?

halfer
  • 19,824
  • 17
  • 99
  • 186
PGDev
  • 23,751
  • 6
  • 34
  • 88

1 Answers1

2

Note that Void is just an empty tuple ().

I think this is due to Remove implicit tuple splat behavior from function applications (SE-0029)

Basically this change says that you can't pass tuples as parameters anymore. You used to be able to either pass parameters by inserting stuff in the () after the function name or pass a tuple representing the parameters

func foo(a: Int, b: Int) {}

let tuple = (a: 1, b: 2)
foo(tuple)

Now you can't.

If we were to transform foo to swift 4, it would look like this:

func foo(a; Int, b: Int) {}
func foo(_ x: (a: Int, b: Int)) {}

So (Void) -> Void represents a function taking a Void parameter. You used to be able to pass nothing because Void is just an empty tuple, which, after the "splat" becomes "no parameters".

Sweeper
  • 213,210
  • 22
  • 193
  • 313