Romeo Sierra
Romeo Sierra

Reputation: 1756

Functions that return another function in Swift

Ola,

Let's say that there is a function named fnOuter(name:String, mks:Double...). I want this function to return another function which I could separately write like fnInner(msg:String)->(String, Double, Double, Character). How one could achieve this? I am a newbie to Swift and tried out the following. But ultimately it ends up with function 'std' was used as a property; add () to call it thrown by the Swift compiler. What am I doing wrong here? How could I fix this? Or is this even possible?

func fnRetFn(name:String, mks:Double...) -> (() -> ((String, Double, Double, Character))){
    var msg = "Hello " + String(name) + "!"

    func calculate() -> (String, Double, Double, Character){
        var total:Double = 0.0
        var i: Double = 0.0
        for mk in mks{
            total += mk
            i += 1
        }

        var avg = total / i

        var grd : Character
        if avg >= 75.0{
            grd = "A"
        }

        else if avg >= 55.0{
            grd = "B"
        }

        else{
            grd = "F"
        } 

        return (msg, total, avg, grd)
    }

    return calculate
}

var outputFn = fnRetFn(name:"Mike", mks:75.3, 87.2)
var std = outputFn
print("\(std.0)")
print("\(std.1)")
print("\(std.2)")
print("\(std.3)")

Edit 1 Please note that the fnInner(msg:String) should return a tuple, not another function.

Upvotes: 0

Views: 1117

Answers (1)

Martin R
Martin R

Reputation: 539685

With

var outputFn = fnRetFn(name:"Mike", mks:75.3, 87.2)
var std = outputFn

both outputFn and std are references to the same function which was returned by fnRetFn(...):

print(std) // (Function)

To call the function you'll have to append the argument list in parentheses. For a function taking no arguments that is the empty list ():

var outputFn = fnRetFn(name:"Mike", mks:75.3, 87.2)
var std = outputFn()

And now std is the tuple returned from calling the "inner" function:

print(std) // ("Hello Mike!", 162.5, 81.25, "A")
print(std.0, std.1, std.2, std.3) // Hello Mike! 162.5 81.25 A

(Unrelated to your problem, but note that both variables should be constants declared with let.)

Upvotes: 2

Related Questions