Swift 2.0 更新:现在函数的行为与方法相同,并且默认情况下两者都是:
- 第一个参数没有外部名称;和
- 其他参数的外部名称与内部名称相同。
除此之外,以下规则仍然适用,只是 # 速记语法现已不复存在。
这里有一个更一般的答案:函数在定义为类外的真正函数和定义为方法时表现不同。此外,init 方法有一个特殊的规则。
功能
假设你定义这个:
func multiply1(f1: Double, f2: Double) -> Double {
return f1 * f2
}
这里的参数名称只是函数的本地,调用函数时不能使用:
multiply1(10.0, 10.0)
如果你想在调用函数时强制使用命名参数,你可以。在每个参数声明前加上其 external 名称。这里,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代码中使用它,它相当于这个声明(查看参数名称):
@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")
在这里,您必须为接受Int 的重载指定start:,但对于接受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 参数。