Обновление для Swift 2.0: теперь функции по умолчанию ведут себя идентично методам, причем для обоих:
- первый параметр не имеет внешнего имени; а также
- остальные параметры имеют внешнее имя, идентичное внутреннему имени.
В остальном правила ниже по-прежнему применяются, за исключением того, что сокращенный синтаксис #
больше не используется.
Вот более общий ответ: функции ведут себя по-разному, когда они определены как истинные функции вне класса, и когда они определены как методы. Более того, у методов инициализации есть особое правило.
Функции
Предположим, вы определили это:
func multiply1(f1: Double, f2: Double) -> Double {
return f1 * f2
}
Имена параметров здесь только локальны для функции и не могут использоваться при вызове функции:
multiply1(10.0, 10.0)
Если вы хотите принудительно использовать именованные параметры при вызове функции, вы можете. Перед каждым объявлением параметра укажите его внешнее имя. Здесь внешнее имя f1
- f1param
, а для f2
мы используем сокращение, в котором мы префикс #
, чтобы указать, что локальное имя также должно использоваться как внешнее имя:
func multiply2(f1param f1: Double, #f2: Double) -> Double {
return f1 * f2
}
Затем необходимо использовать именованные параметры:
multiply2(f1param: 10.0, f2: 10.0)
Методы
С методами дело обстоит иначе. По умолчанию, как вы обнаружили, все параметры, кроме первого, имеют имена. Предположим, у нас есть это, и рассмотрим метод multiply1
:
class Calc {
func multiply1(f1: Double, f2: Double) -> Double {
return f1 * f2
}
func multiply2(f1param f1: Double, f2: Double) -> Double {
return f1 * f2
}
func multiply3(f1: Double, _ f2: Double) -> Double {
return f1 * f2
}
}
Затем вы должны использовать имя второго (и следующих, если есть) параметров:
let calc = Calc()
calc.multiply1(1.0, f2: 10.0)
Вы можете принудительно использовать именованный параметр для первого аргумента, указав для него внешнее имя, например для функций (или добавив к его локальному имени префикс #
, если вы хотите использовать то же внешнее имя, что и его локальное имя). Затем вы должны использовать его:
calc.multiply2(f1param: 10.0, f2: 10.0)
Наконец, вы можете объявить внешнее имя _
для других следующих аргументов, указывая, что вы хотите вызвать свой метод без использования именованных параметров, например:
calc.multiply3(10.0, 10.0)
Примечание о совместимости: если вы поставите перед class Calc
аннотацию @objc
, вы сможете использовать ее из кода Objective-C, и это эквивалентно этому объявлению (посмотрите на имена параметров): em >
@interface Calc
- (double)multiply1:(double)f1 f2:(double)f2;
- (double)multiply2WithF1param:(double)f1 f2:(double)f2;
- (double)multiply3:(double)f1 :(double)f2;
@end
Методы инициализации
Правило немного отличается для init
методов, где все параметры по умолчанию имеют внешнее имя. Например, это работает:
class Calc {
init(start: Int) {}
init(_ start: String) {}
}
let c1 = Calc(start: 6)
let c2 = Calc("6")
Здесь вы должны указать start:
для перегрузки, которая принимает Int
, но вы должны опустить его для перегрузки, которая принимает String
.
Примечание о совместимости: этот класс будет экспортирован в Objective-C следующим образом:
@interface Calc
- (instancetype)initWithStart:(NSInteger)start __attribute__((objc_designated_initializer));
- (instancetype)init:(NSString *)start __attribute__((objc_designated_initializer));
@end
Закрытие
Предположим, вы определяете тип закрытия следующим образом:
typealias FancyFunction = (f1: Double, f2: Double) -> Double
Имена параметров будут вести себя очень похоже на имена в методе. Вам нужно будет указать имена для параметров при вызове закрытия, если вы явно не установите для внешнего имени значение _.
Например, выполнение закрытия:
fund doSomethingInteresting(withFunction: FancyFunction) {
withFunction(f1: 1.0, f2: 3.0)
}
Практическое правило: даже если они вам не нравятся, вам, вероятно, следует попытаться продолжать использовать именованные параметры, по крайней мере, всякий раз, когда два параметра имеют один и тот же тип, чтобы устранить их неоднозначность. Я бы также сказал, что хорошо также указать хотя бы все параметры Int
и Boolean
.
person
Jean-Philippe Pellet
schedule
04.06.2014
NSObject
)? Он отмечен знаком@objc
? Если это так, компилятор предполагает, что он может быть вызван из Objective-C, поэтому его методы должны иметь форму, совместимую с соглашениями о вызове / именовании методов Objective-C. - person Ken Thomases   schedule 05.06.2014_
передfactor2
, напримерfunc multiply(factor1:Int, _ factor2:Int) {...}
. - person Hlung   schedule 18.04.2015func multiply(factor1:Int, factor2:Int)
наfunc multiply(factor1:Int, _ factor2:Int)
. Это НЕ взлом, а синтаксис официального языка. - person Jacob R   schedule 03.07.2015