Хотя свойство и метод имеют одно и то же базовое имя add
, они имеют разные полные имена.Полное имя метода - add(_:)
из-за того, что у него есть параметр (без метки аргумента), а полное имя свойства просто add
.Тот факт, что их полные имена различаются, позволяет им перегружать друг друга.
Если бы у метода не было параметров, то компилятор не допустил бы перегрузку, поскольку их полные имена теперь и add
, ипоэтому конфликт:
class AClass {
var add: () -> Int {
return {
return 1
}
}
func add() -> Int { // error: Invalid redeclaration of 'add()'
return 2
}
}
Всегда ли компилятор получает переменную, а не вызывает функцию?
Предполагая, что они имеют одинаковый тип функции (например, в вашем примере), тогда да.Существует правило ранжирования перегрузки, которое предпочитает переменные функциям:
// 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
Чтобы вызвать метод, вы можете использовать ссылку на него по его полному имени, например:
let a = AClass()
print(a.add(_:)(1)) // 21