akshayc
akshayc

Reputation: 494

Nested function overloading in Swift

Overloading methods in Swift works as expected, but when I try to overload nested functions, such as

func foo() {
    func bar(param: Int) {
        // do stuff
    }
    func bar(param: Double) {
        // do stuff
    }

    // call functions here
}

I get an error saying Definition conflicts with previous value. Why does this happen?

Upvotes: 3

Views: 400

Answers (2)

Matteo Piombo
Matteo Piombo

Reputation: 6726

IMHO this is clearer if you consider this variation:

func foo() {

    let bar: (param: Int) -> () = { p in
        // do stuff
    }

    func bar(param: Double) {
        // do stuff
    }

    // call functions here
}

With your first bar function definition you are just declaring a constant of type (param: Int) -> (). Thus with your second declaration you are declaring another constant of different type (param: Double) -> () but having the same name as the already declared bar.

In short it's just like you wrote:

let bar: Int = 0
let bar: Double = 0.0

In which case compiler will complain as well.

Hope this helps.

Upvotes: 3

avismara
avismara

Reputation: 5149

Good question.

Note that this behaviour/restriction is not documented and the answer is my best guess.

Consider this following piece of code:

func foo() -> (param:Int)->() {
    func bar(param: Int) {
        // do stuff
    }
    return bar
}

The function will return the closure bar. If you were to have another closure named bar within the same function, like this...

func foo() -> (param:Int)->() {
    func bar(param: Int) {
        // do stuff
    }
    func bar(param: Float) {
        // do stuff
    }
    return bar
}

...they would have conflicting names and the compiler doesn't know what to return. This is same as the following piece of code which you would readily agree to be wrong:

func foo() -> Int {
    let a:Int = 0
    let a:Int = 0 //Error
    return a
}

More observation

The behaviour of a similar set of functions inside a class is weird.

class Test {
    func foo(param:Float) {
        let bar = { (param:Int) -> () in
            //do stuff
        }
    }
    func foo(param:Int) {
        let bar = { (param:Int) -> () in
            //do stuff
        }
    }
    func anotherFoo() {
        println(self.foo) //Compile time error - Ambiguous use of foo
    }
}

All though...

class Test {
    func foo(param:Float) {
        let bar = { (param:Int) -> () in
            //do stuff
        }
    }
    func anotherFoo() {
        println(self.foo) //Compiles
    }
}

Interesting.

Upvotes: 1

Related Questions