What does $0 and $1 mean in Swift Closures?
$0
is the first parameter passed into the closure. $1
is the second parameter, etc. That closure you showed is shorthand for:
let sortedNumbers = numbers.sort { (firstObject, secondObject) in
return firstObject > secondObject
}
What does $0 represent in closures in Swift?
It's a shorthand argument name.
From the Swift Book:
“Swift automatically provides shorthand argument names to inline
closures, which can be used to refer to the values of the closure’s
arguments by the names $0, $1, $2, and so on.”— Apple Inc. “The Swift Programming Language.”
It helps reduce the verbosity of your code (sometimes at the cost of readability), so you don't have to write out long argument lists when defining closures.
What does $1 ++ $0 mean in the closure for Swift?
$0
is the first parameter passed into the closure.
$1
is the second parameter.
++
is a custom infix operator
infix operator ++
private func ++<Element>(element: Element, list: ListNode<Element>) -> ListNode<Element> {
return list.insert(element: element)
}
It will insert the element on the right to list on right of the operator
What does $0.1, $0.0, etc. mean in Swift?
$0
is a shorthand name for first argument passed to closure. In this case, as you're mapping a Dictionary
, that argument is a tuple - hence $0.0
is a key, and $0.1
is a value
For more info on shorthand argument names, see Swift documentation on closures
Swift: Can someone explain this syntax `numbers.sort { $0 $1 }` for me?
@the_UB and @moonvader are both right, but I just thought that I would extend the example from @moonvader a bit, just to show you how we end up with $0 > $1
If you look at the example in "The Swift Programming Language" about Closure Expressions you can see that to sort an array you call the sort
method which can then take a function as a parameter.
This function must take two parameters and compare them, and then return a boolean.
So if we have this array:
let numbers = [4, 6, 8, 1, 3]
and this method
func sortBackwards(val1: Int, val2: Int) -> Bool {
print("val1: \(val1) - val2: \(val2)" )
return val1 > val2
}
We can sort the elements like so:
numbers.sort(sortBackwards) //gives us [8, 6, 4, 3, 1]
The sort
method will use our sortBackwards
method on each of the elements in the array and compare them.
Here's the output of the print
val1: 6 - val2: 4
val1: 8 - val2: 4
val1: 8 - val2: 6
val1: 1 - val2: 4
val1: 3 - val2: 1
val1: 3 - val2: 4
OK, let's reduce that.
Instead of defining a function, we can add that directly as a parameter to the sort
method like so:
numbers.sort({(val1: Int, val2: Int) -> Bool in
return val1 > val2
})
And we still end up with [8, 6, 4, 3, 1] (how fortunate!)
OK, the next thing we can do is what in "The Swift Programming Language" (the link above) is called "Infering Type From Context". As we call this method on an array of Int
s, Swift can figure out that our val1
and val2
parameters must be Int
s too, there's no need for us to tell it. So, lets remove the types. That leaves us with:
numbers.sort({val1, val2 in
return val1 > val2
})
And still the same result.
OK, getting there. The next thing we can do is what in the book is called "Implicit Returns from Single-Expression Closures"
As our comparison can be done in one line there's no need for us to use return
. So:
numbers.sort({val1, val2 in val1 > val2})
Still gives us [8, 6, 4, 3, 1]
Finally we're getting to what @moonvader used much much less words to explain :-) namely "Shorthand Argument Names"
As it says in the book:
Swift automatically provides shorthand argument names to inline closures, which can be used to refer to the values of the closure’s arguments by the names $0, $1, $2, and so on.
So, in our example, val1
can be replaced by $0
and val2
can be replaced by $1
Which gives us:
numbers.sort({$0 > $1})
And still we get [8, 6, 4, 3, 1]
We can then continue to use a "Trailing Closure", which means that if the last parameter of a function is a closure, we can add that parameter "outside" the function.
So we end up with:
numbers.sort{$0 > $1}
And the outcome is still [8, 6, 4, 3, 1]
Hope that helps to clarify things.
Contextual closure type '() - Text' expects 0 arguments, but 1 was used in closure body
You have two closures, so $0 from first one (even if it would be correct, but with _ in
you just ignore it) is not available in second one.
The fix is to use argument explicitly, like
ForEach(1..<18) { index in // << here !!
NavigationLink(destination: chapterrun()) {
Text("Chapter \(index)") // << here !!
}
}
Related Topics
Disable Warning Dialog If Bluetooth Is Powered Off iOS
Measuring Time Accurately in Swift for Comparison Across Devices
In-App Purchase Sandbox Environment Loop
How to Add Firebase to Today Extension iOS
How to Detect "Clear" Notifications
Sort Array by Distance Near User Location from Firebase
Sprite Kit Set Min. and Max. for Jump
How to Get an Error Description When Playback Fails on Mpmovieplayercontroller
Mask Uiview with Uibezierpath - Stroke Only
How to Switch to Speaker Output When Bluetooth Headsets Are Connected
Insert String at Cursor Position of Uitextfield
Changing Uipageviewcontroller's Page Programmatically Doesn't Update the Uipagecontrol
How to Create a Uiimage with Uibezierpath
Uipageviewcontroller Gesture Is Calling Viewcontrollerafter: But Doesn't Animate
How to Upload Multiple Image on Firebase Using Swift
Executefetchrequest Throw Fatal Error: Nsarray Element Failed to Match the Swift Array Element Type