Adele
Adele

Reputation: 39

Passing an instance to an instance method makes a reference to that instance method?

In iOS 13 Programming Fundamentals with Swift by Matt Neuburg I came across this strange bit of code

class MyClass {
    var s = ""
    func store(_ s:String) {
        self.s = s
    }
}

class ViewController: UIViewController {

    override func viewDidLoad() {
        let m = MyClass()
        let f = MyClass.store(m) // what just happened!?
        f("howdy")
        print(m.s) // howdy
    }

}

Apparently f has the type () -> () (thats what it says on debugger at least) and yet on the next line we are passing a string to it.

Based of the result it seems that f has somehow become a reference to the store method which is why when m.s is printed you get "howdy". But this code really baffles me and an explanation of what is going on would be much appreciated.

I don't even understand how MyClass.store is legal because store is an instance method and in this case it is being referred to as if it was a static method.

Upvotes: 0

Views: 153

Answers (2)

matt
matt

Reputation: 535315

The next words in the book tell you the answer:

The reason is that an instance method is actually a curried static/class method composed of two functions — one function that takes an instance, and another function that takes the parameters of the instance method. After that code, f is the second of those functions, and can be called as a way of passing a parameter to the store method of the instance m.

Upvotes: 3

Stuart Sharpe
Stuart Sharpe

Reputation: 601

Any instance method in Swift can also be called statically, but if you do that you need to pass it an instance to operate on. So, for example, you could choose to sort an array like this:

let sortedArray = Array.sort([13, 8, 21, 3, 1, 34, 5, 1, 2])

So, while the instance method is defined as store(_ s: String), the compiler is also implicitly creating a static variant of the method that’s more like static func store(_ self: MyClass) -> ((String)->()). I’m not sure why the debugger would tell you f is ()->() - that sounds like Xcode hijinks and shenanigans.

This property of Swift has some pretty cool uses, though. See https://www.swiftbysundell.com/articles/first-class-functions-in-swift

Upvotes: 2

Related Questions