当前位置: 首页 > 面试题库 >

为什么函数调用在Swift中需要参数名称?

马寒
2023-03-14
问题内容

我在课堂上有这个功能:

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

我尝试使用此函数来调用该html" target="_blank">函数:

var multResult = calculator.multiply(9834, 2321)

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

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

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


问题答案:

Swift 2.0更新 :现在,默认情况下,函数的功能与方法相同,并且对于两种方法而言:

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

除此之外,下面的规则仍然适用,只是#速记语法已消失。

这是一个更一般的答案:函数在类之外定义为真函数时以及在定义为方法时的行为会有所不同。而且,初始化方法有一个特殊的规则。

功能

假设您定义了以下内容:

func multiply1(f1: Double, f2: Double) -> Double {
    return f1 * f2
}

这里的参数名称仅在函数 本地 ,并且在调用函数时不能使用:

multiply1(10.0, 10.0)

如果要在调用函数时强制使用命名参数,则可以。在每个参数声明的 外部
加上前缀。在这里,的外部名称f1f1param,对于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")

在这里,您必须指定start:接受的重载Int,但对于接受的重载则必须将其忽略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)
}

根据经验:即使您不喜欢它们,也应该至少在两个参数具有相同类型的情况下尝试继续使用命名参数,以消除歧义。我还要指出,也至少要命名all
IntBooleanparameters 很好。



 类似资料:
  • 问题内容: 创建接口方法时,我们不能像在 java中 那样做: 相反,我注意到我们还需要给参数名称lile: 同样,接口实现者不需要具有与接口方法中相同的参数名称。 我在这里发现了有关c#的类似问题。他们提到了 命名参数的一种情况,但是我没有在Java中找到任何其他相关原因。 问题答案: 从技术角度来看,这是没有必要的。 我一直将其作为语法规范化和文档帮助。 这样有: 没有理由区分类和接口方法的语

  • 问题内容: 我读了一些有关闭包的文章,到处都看到了,但是没有明确的解释-每次我被告知要使用它时……: 好的,我看到我们将创建一个新的匿名函数,然后执行它。因此,在此之后,此简单的代码应该可以工作了(并且可以): 我的问题是这里发生了什么魔术?我以为在写的时候: 然后将创建一个新的未命名函数,如函数“”(msg)… 为什么它需要在同一行? 您能给我一些帖子或给我一个解释吗? 问题答案: 将分号放在函

  • 我问这个问题是因为在Python和Java中,如果父类构造函数需要0参数,则不需要调用super()。 Javascript 蟒蛇 Java

  • 问题内容: 必须使用无参数构造函数(像Hibernate这样的工具会在此构造函数上使用反射来实例化对象)。 我得到了这个手挥手的答案,但是有人可以进一步解释吗?谢谢 问题答案: hibernate,并且通常通过反射创建对象的代码用于创建类的新实例。此方法需要一个公共的无参数构造函数才能实例化该对象。对于大多数用例,提供无参数构造函数不是问题。 有一些基于序列化的技巧可以解决没有no-arg构造函数

  • 问题内容: 在Swift中,调用第一个参数时会使用参数名称。为什么不使用名字? 使用Swift手册的变体; 这会起作用; 但这给了我“调用中的外部参数标签’amount’” 是否有这个原因,或者这是“按其原样”的事物之一? 问题答案: 这是遵循Objective-C习惯的惯例,第一个参数的名称与方法名称结合在一起。这是一个例子: 您可以像这样调用方法: 通过将参数的名称合并到方法的名称中,可以使阅

  • 想改进这个问题吗 通过编辑此帖子,添加详细信息并澄清问题。 我问这个问题是因为在Python和Java中,如果父类构造函数需要0参数,则不需要调用super()。 Javascript 蟒蛇 Java语言