methods - 为什么函数调用需要 Swift 中的参数名称?

标签 methods swift named-parameters

我在一个类中有这个函数:

func multiply(factor1:Int, factor2:Int) -> Int{
    return factor1 * factor2
}

我试着用这个调用函数:

var multResult = calculator.multiply(9834, 2321)

问题是编译器希望它看起来更像这样:

var multResult = calculator.multiply(9834, factor2: 2321)

为什么第一个会导致错误?

最佳答案

Swift 2.0 更新:现在函数的行为与方法相同,默认情况下两者都是:

  • 第一个参数没有外部名称;和
  • 其他参数的外部名称与内部名称相同。

除此之外,下面的规则仍然适用,只是 # 简写语法现在消失了。


这里有一个更一般的答案:函数在定义为类外的真正函数时和定义为方法时表现不同。此外,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)
}

根据经验:即使您不喜欢它们,您也应该至少在两个参数具有相同类型时尝试继续使用命名参数,以消除它们的歧义。我还认为,最好也至少命名所有 IntBoolean 参数。

关于methods - 为什么函数调用需要 Swift 中的参数名称?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24045890/

相关文章:

methods - 如何命名一个可能做或不做某事的方法?

php - 了解 fetch_assoc()

swift - 详细 View Controller 后退按钮标题不随主视图 Controller 标题更新

java - CallableStatement setInt 命名参数异常

Scala 命名和默认参数以及隐式参数

python - 动态添加关键参数到方法

Java - 按值传递示例

c# - 从 C# 中的函数中获取当前正在执行的函数的名称

swift - swift 如何在转换的继承类上传递重写方法调用?

ios - iOS 和 tvOS 应用程序上的相同 viewController,UIPickerViewDelegate 在 tvOS 上不可用