我在一个类中有这个函数:
func multiply(factor1:Int, factor2:Int) -> Int{
return factor1 * factor2
}
我尝试使用以下代码调用函数:
var multResult = calculator.multiply(9834, 2321)
问题在于编译器希望它看起来更像这样:
var multResult = calculator.multiply(9834, factor2: 2321)
为什么第一个会导致错误?
我在一个类中有这个函数:
func multiply(factor1:Int, factor2:Int) -> Int{
return factor1 * factor2
}
我尝试使用以下代码调用函数:
var multResult = calculator.multiply(9834, 2321)
问题在于编译器希望它看起来更像这样:
var multResult = calculator.multiply(9834, factor2: 2321)
为什么第一个会导致错误?
除此之外,以下规则仍然适用,只是#
简写语法现在已经消失了。
这里有一个更通用的解答:在类外定义真正的函数时和在类中定义方法时,函数的行为不同。此外,init方法有一条特殊规则。
假设您定义了以下内容:
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 代码中使用它,并且它等效于此声明(请查看参数名称):
@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
参数命名。Smalltalk程序员喜欢使用冗长和描述性的语言,而不是简洁和无意义的语言。他们可以这样做,因为他们的集成开发环境会为他们完成大部分此类输入。
由于您在示例代码中使用了calculator.multiply()
,我认为这个函数是calculator
对象的一个方法。
Swift从Objective-C继承了很多东西,这就是其中之一:
在Objective-C中,您会这样做(假设):
[calculator multiply:@9834 factor2:@2321];
在Swift中的等效写法为:(参考链接)
calculator.multiply(9834, factor2:2321);
class Calculator {
func multiply(factor1:Int, factor2:Int) -> Int{
return factor1 * factor2
}
func multiply(factor1:Int, factor2:Int, factor3:Int) -> Int{
return factor1 * factor2 * factor3
}
}
这里有两种不同的方法,分别为multiply(factor2)和multiply(factor2 factor3)。
这个规则只适用于方法,如果您像在类外声明函数一样声明它,则函数调用不需要参数名。
func multiplyFactor1(factor1: Int, factor2:Int) {}
因此,在调用该方法时,省略了第一个参数以避免重复使用它的名称。myCalculator.multiplyFactor1(2, facto2:2)
比myCalculator.multiplyFactor1(factor1: 2, facto2:2)
更易读。 - Danielfunc refresh(obj:Obj, _ method: (Obj)->Void = setValue) {
method(element)
}
func setValue(obj:Obj){
obj.value = "someValue"
}
refresh(someObj,setValue)
NSObject
)?它是否标记为@objc
?如果是,编译器会假定它可能从Objective-C中调用,因此其方法必须符合Objective-C的方法调用/命名约定。 - Ken Thomasesfactor2
前面加上下划线_
,例如func multiply(factor1:Int, _ factor2:Int) {...}
。 - Hlungfunc multiply(factor1:Int, factor2:Int)
替换为func multiply(factor1:Int, _ factor2:Int)
。这不是黑客行为,而是官方语言语法。 - Jacob R