Class have a variable name same as function name
In Swift, instance methods are curried functions. Which means your add
method is actually
static func add(_ self: AClass) -> (Int) -> Int
This is why the property gets chosen over the function. Calling AClass.add(a)(1)
yelds the expected result, the function gets called.
Now, why does the compiler allows this name clashing if the first place? I'm not sure, but I assume it has to do with the fully qualified name of those two entities. The property is simply add
, while the function is add(_:)
.
While both the property and method share the same base name add
, they have different full names. The method's full name is add(_:)
due to the fact that it has a parameter (with no argument label), and the property's full name is just add
. The fact that their full names differ is what allows them to overload each other.
If the method had no parameters, then the compiler would not have allowed the overload, as their full names are now both add
and therefore conflict:
class AClass {
var add: () -> Int {
return {
return 1
}
}
func add() -> Int { // error: Invalid redeclaration of 'add()'
return 2
}
}
Does the compiler always get the variable rather than call the function?
Assuming they have the same function type (such as in your example), then yes. There is an overload ranking rule that favours variables over functions:
// If the members agree on instance-ness, a property is better than a // method (because a method is usually immediately invoked). if (!decl1->isInstanceMember() && decl2->isInstanceMember()) score1 += weight; else if (!decl2->isInstanceMember() && decl1->isInstanceMember()) score2 += weight; else if (isa<VarDecl>(decl1) && isa<FuncDecl>(decl2)) score1 += weight; else if (isa<VarDecl>(decl2) && isa<FuncDecl>(decl1)) score2 += weight;
lib/Sema/CSRanking.cpp
In order to call the method, you can use refer to it by its full name, for example:
let a = AClass()
print(a.add(_:)(1)) // 21