You don't indicate exactly what error you are getting in the playground, so it's a little difficult to assess what's wrong with your code, but in the example you give you are actually passing two parameters to makeArray
, not one.
The signature of makeArray
is:
func makeArray(size: Int, using generator: () -> Int) -> [Int]
meaning that the second parameter is a function that takes no input and returns an Int
. So given a function called, for example, generateRolls
, you would call it like so:
func generateRolls() -> Int {
Int.random(in: 1...20)
}
let rolls = makeArray(size: 50, using: generateRolls)
But we can simplify by replacing the explicit function generateRolls
with a closure:
let rolls = makeArray(size: 50, using: { Int.random(in: 1...20) })
Swift has a nifty feature called trailing closures, where if the final parameter is a closure* you can write the closure after the closing parentheses "even though the trailing closure is still an argument to the function", that allow us to clean up that call site:
let rolls = makeArray(size: 50) {
Int.random(in: 1...20)
}
So you are still passing two parameters to makeArray
, even if it doesn't look like it.
Admittedly, it takes some getting used to when you first pick up Swift, but it really makes your code easier to read and nicer looking.
*And, since last year, you can even have multiple trailing closures. So a something like this, that takes two function params:
Button.init(action: () -> Void, label: () -> Label)
can be written as:
Button {
//do some action here
} label: {
//show some label here
}
You'll notice there are no parentheses but you are still calling the init
function with two parameters.