加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

方法 – 为什么函数调用需要Swift中的参数名?

发布时间:2020-12-14 06:11:46 所属栏目:百科 来源:网络整理
导读:我有一个类中的这个功能: func multiply(factor1:Int,factor2:Int) - Int{ return factor1 * factor2} 我尝试调用该函数使用: var multResult = calculator.multiply(9834,2321) 问题是编译器希望它看起来更像这样: var multResult = calculator.multiply
我有一个类中的这个功能:
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)

互操作性注释:如果您使用@objc注释为Calc类型添加前缀,那么您可以从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")

在这里,你必须指定start:对于接受一个I??nt的重载,但是你必须忽略它接受一个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和布尔参数。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读