SLN SLN - 5 months ago 12
Swift Question

Very confused, how and when the arguments of the nested function get called and passed value in?

The code example comes from the office swift document

let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
func backwards(s1: String, _ s2: String) -> Bool {
return s1 > s2
}
var reversed = names.sort(backwards)


backwards
function had been used as the argument of the method
sort(_:)
.
The function
backwards
returns boolean values, however, when I tried this
names.sort(true)
I've got an error from the compiler! Why there are no errors in the example code? Another question is, what's going on with
s1
and
s2
as the arguments? When did they get called? How the strings in
names
array get passed into them?

Thanks a lot for your help

Answer

The function backwards returns boolean values, however, when I tried this names.sort(true)

The sort method being used is actually the sort(isOrderedBefore: (Element, Element) -> Bool) method which takes a comparison function as a parameter. The function has to take the particular set of parameters specified in the interface, i.e. a function that takes two Element parameters and returns a Bool.

As gnasher explained, you're getting an error because true is a value, not a function. You could write a function that returns true though, and that should work. Using Swift's trailing closure syntax, you could write:

names.sort() {return true}

That obviously wouldn't be very useful for actual sorting, but it shows how to make your example work.

what's going on with s1 and s2 as the arguments? When did they get called? How the strings in names array get passed into them?

That's the job of the sort method. It's an instance method belonging to ArraySlice, and it compares the elements in the slice two at a time to determine how they should be ordered. The actual comparison is done using the comparison method that you pass in, so that you can use the same sort method to sort your array using any sort order you can dream up. Try doing this:

let names = ["Harry", "David", "Susan", "Alice"]
let sortedNames = names.sort() {
    print($0, $1)
    return $0 < $1
}

And you should see a list of output lines as sort() calls your comparison method repeatedly.