user2727195
user2727195

Reputation: 7330

passing a function along with an inout parameter

the constructor is receiving two parameters.

a) a function whose type is a function receiving an inout params (so it can change the params)

b) passing your params object, expecting the function passed will be able to modify the object

then trigger the apply method, so your passed function can change the passed params.

If there's a solution with passing params in a closure, that'd work too.

class Test {

    var params: Any?

    var myFunc: (inout params: Any?) -> () = { (inout params: Any?) in return } //default value


    //constructor receving a function and a address to inout params object
    init(myFunc: (inout params: Any?) -> (), inout params: Any?) {
        self.myFunc = myFunc
        self.params = params
    }

    //call the passed function (extern) and pass the address of given params
    func apply() {
        self.myFunc(params: &self.params)
    }
}

func extern(inout params: Any?) {
    var a = params as [String: Int]
    a["factor"] = 11
}

var p: Any = ["factor": 10]
var test = Test(myFunc: extern, params: &p)

test.apply() //p["factor"] should be 11 now here

p["factor"] as [String: Int]

My second attempt using closures

//Utility

class Test {

    var closure: () -> Any

    var myFunc: (message: String, closure: () -> Any) -> () = { (message: String, closure: () -> Any) in return }

    init(myFunc: (message: String, closure: () -> Any) -> (), closure: () -> Any) {
        self.myFunc = myFunc
        self.closure = closure
    }

    func apply(message: String) {
        self.myFunc(message: message, closure: self.closure)
    }

}

//users of the utility

func extern(message: String, closure: () -> Any) {
    println(message)
    var name = closure() as [String: String]
    name["name"] = "Doe"
}

var name: Any = ["name": "John"]

var test = Test(myFunc: extern, closure: {name})
test.apply("hello ")
name //it's still John here

3rd attempt using AnyObject and closures and of course it works but still need your opinion guys for a best strategy.

//Utility

class Test {

    var closure: () -> AnyObject

    var myFunc: (message: String, closure: () -> AnyObject) -> () = { (message: String, closure: () -> AnyObject) in return }

    init(myFunc: (message: String, closure: () -> AnyObject) -> (), closure: () -> AnyObject) {
        self.myFunc = myFunc
        self.closure = closure
    }

    func apply(message: String) {
        self.myFunc(message: message, closure: self.closure)
    }

}

//users of the utility

func extern(message: String, closure: () -> AnyObject) {
    println(message)
    var name: Name = closure() as Name
    name.name = "Doe"
}

class Name {
    var name = "John"
}

var name = Name()

var test = Test(myFunc: extern, closure: {name})
test.apply("hello ")
name //it's changed here

Upvotes: 0

Views: 563

Answers (1)

Nate Cook
Nate Cook

Reputation: 93276

It seems like you're trying to reinvent closures here. One point of closures is that they can capture references to the values around them. This should do what you're describing above, and lets you keep using proper types for your variables, rather than falling back on Any:

class Test {
    var myFunc: () -> Void = { }

    init(myFunc: () -> Void) {
        self.myFunc = myFunc
    }

    func apply() {
        self.myFunc()
    }
}

func extern(inout dict: [String: Int]) {
    dict["factor"] = 11
}

var p = ["factor": 10]

let test = Test {
    extern(&p)
}

test.apply() // p["factor"] is now 11 here

println(p)
// ["factor": 11]

Upvotes: 1

Related Questions