为什么函数调用需要 Swift 中的参数名称? [英] Why does a function call require the parameter name in Swift?

查看:21
本文介绍了为什么函数调用需要 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)
}

<小时>

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

这篇关于为什么函数调用需要 Swift 中的参数名称?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆