为什么函数调用需要 Swift 中的参数名称? [英] Why does a function call require the parameter name in Swift?
问题描述
我在一个类中有这个函数:
I have this Function in a class:
func multiply(factor1:Int, factor2:Int) -> Int{
return factor1 * factor2
}
我尝试使用这个调用函数:
I try to call the function using this:
var multResult = calculator.multiply(9834, 2321)
问题在于编译器希望它看起来更像这样:
The problem is that the compiler wants it to look more like this:
var multResult = calculator.multiply(9834, factor2: 2321)
为什么第一个会导致错误?
Why does the first one cause an error?
推荐答案
Swift 2.0 的更新:现在函数的行为与方法相同,并且默认情况下:
Update for Swift 2.0: Now functions behave identically to methods, and for both, by default:
- 第一个参数没有外部名称;和
- 其他参数的外部名称与内部名称相同.
除此之外,下面的规则仍然适用,只是 #
速记语法现已消失.
Other than that, the rules below still apply, except that the #
shorthand syntax is now gone.
这是一个更一般的答案:函数在定义为类之外的真正函数时和定义为方法时的行为不同.此外,init 方法有一个特殊的规则.
Here's a more general answer: functions behave differently when defined as true functions outside a class, and when defined as methods. Moreover, init methods have a special rule.
假设你定义了这个:
func multiply1(f1: Double, f2: Double) -> Double {
return f1 * f2
}
这里的参数名只是函数的局部,不能在调用函数时使用:
Parameter names are here only local to the function, and cannot be used when calling the function:
multiply1(10.0, 10.0)
如果你想在调用函数时强制使用命名参数,你可以.使用其外部名称作为每个参数声明的前缀.这里,f1
的外部名称是 f1param
,对于 f2
,我们使用速记,在它前面加上 #
表示本地名称也用作外部名称:
If you want to force using named parameters when calling the function, you can. Prefix each parameter declaration with its external name. Here, the external name of f1
is f1param
, and for f2
, we use the shorthand where we prefix it by #
to indicate that the local name is to be used as the external name as well:
func multiply2(f1param f1: Double, #f2: Double) -> Double {
return f1 * f2
}
那么,必须使用命名参数:
Then, named parameters must be used:
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
}
}
然后,您必须使用第二个(以及后面的,如果有)参数的名称:
Then, you have to use the name of the second (and following, if any) parameters:
let calc = Calc()
calc.multiply1(1.0, f2: 10.0)
您可以通过为其提供外部名称来强制为第一个参数使用命名参数,例如函数(或者如果您想使用相同的外部名称,则在其本地名称前加上 #
作为其本地名称).然后,你必须使用它:
You can force to use a named param for the first argument by providing an external name for it, like for functions (or prefixing its local name with #
if you want to use the same external name as its local name). Then, you have to use it:
calc.multiply2(f1param: 10.0, f2: 10.0)
最后,你可以为后面的其他参数声明一个外部名称_
,表示你想在不使用命名参数的情况下调用你的方法,像这样:
Finally, you can declare an external name of _
for the other following arguments, indicating that you want to call your method without using named parameters, like this:
calc.multiply3(10.0, 10.0)
互操作性说明:如果您在 class Calc
前面加上 @objc
注释,那么您可以在 Objective-C 中使用它代码,相当于这个声明(看参数名):
Interoperability note: If you prefix class Calc
with the @objc
annotation, then you can use it from Objective-C code, and it is equivalent to this declaration (look at parameter names):
@interface Calc
- (double)multiply1:(double)f1 f2:(double)f2;
- (double)multiply2WithF1param:(double)f1 f2:(double)f2;
- (double)multiply3:(double)f1 :(double)f2;
@end
<小时>
初始化方法
init
方法的规则略有不同,默认情况下,所有参数都有一个外部名称.例如,这有效:
Init Methods
The rule differs a bit for init
methods, where all parameters have an external name by default. For instance, this works:
class Calc {
init(start: Int) {}
init(_ start: String) {}
}
let c1 = Calc(start: 6)
let c2 = Calc("6")
这里,你必须为接受Int
的重载指定start:
,但你必须为接受String的重载省略它代码>.
Here, you have to specify start:
for the overload that accepts an Int
, but you must omit it for the overload that accepts a String
.
互操作性说明:这个类会像这样导出到 Objective-C:
Interoperability note: this class would get exported to Objective-C like this:
@interface Calc
- (instancetype)initWithStart:(NSInteger)start __attribute__((objc_designated_initializer));
- (instancetype)init:(NSString *)start __attribute__((objc_designated_initializer));
@end
<小时>
关闭
假设你定义了一个这样的闭包类型:
Closures
Assume you define a closure type like this:
typealias FancyFunction = (f1: Double, f2: Double) -> Double
参数名称的行为与方法中的参数名称非常相似.除非您明确将外部名称设置为 _,否则您必须在调用闭包时为参数提供名称.
The parameter names will behave very similar to those in a method. You will have to provide the names to the parameters when calling the closure unless you explicitly set the external name to _.
例如执行闭包:
fund doSomethingInteresting(withFunction: FancyFunction) {
withFunction(f1: 1.0, f2: 3.0)
}
<小时>
作为一个经验法则:即使您不喜欢它们,您也应该尝试至少在两个参数具有相同类型时继续使用命名参数,以消除它们的歧义.我还认为最好至少命名所有 Int
和 Boolean
参数.
这篇关于为什么函数调用需要 Swift 中的参数名称?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!