Reputation: 494
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
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
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