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

查看:107
本文介绍了为什么函数调用在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方法:


Methods

Things are different for methods. By default, all but the first parameter are named, as you've discovered. Suppose we have this, and consider the multiply1 method:

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参数.


As a rule of thumb: even if you dislike them, you should probably try to keep using named parameters at least whenever two parameters have the same type, in order to disambiguate them. I'd also argue that it's good to also name at least all Int and Boolean parameters.

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

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