使用和不使用默认参数声明的调用函数会导致不同的结果?

时间:2015-01-11 10:33:11

标签: swift

我在操场上编写了用于测试(学习)目的的代码:

import Cocoa
func DoIt(a: Int, b: Int, c :Int = 0) -> Int {
    return a + b + c;
}
func DoIt(a: Int, b: Int, c :NSObject) -> Int {
    return a * b * c.description.lengthOfBytesUsingEncoding(NSUTF8StringEncoding);
}

当我使用它时,我得到了这个:

DoIt(4, 5, 6);            // result: 20
var obj = NSObject();     // result: NSObject
DoIt(4, 5, obj);          // result: 520

我期望在执行DoIt(Int, Int, Int)时调用第一个函数DoIt(4, 5, 6);但显然正在调用另一个函数66去了哪里?看起来NSObject被隐式转换为c: Int,在objective-c中至少会发出警告。
这是为什么?

奇怪的是,如果我需要上一个= 0(删除DoIt(4, 5, 6); // result: 15 var obj = NSObject(); // result: NSObject DoIt(4, 5, obj); // result: 520 ),那么它会按预期工作。

$ swiftc \
   -emit-ir /Users/nacho4d/Desktop/function2/function2/main.swift \
   -sdk Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk 

编辑1 :添加了红外线 如果这有助于理解发生了什么,我发出了以下命令,结果在gist链接中:https://gist.github.com/nacho4d/94fdb72d8a3fee0c09e5

{{1}}

1 个答案:

答案 0 :(得分:4)

来自Swift文档中的"Functions"(强调添加):

  

具有默认值的参数的外部名称

     

在大多数情况下,提供(因此需要)一个是有用的   具有默认值的任何参数的外部名称。这确保了   如果值是,则该参数的参数在目的中是明确的   在调用函数时提供。

     

为了简化此过程,Swift提供了自动外部名称   适用于任何具有默认值的参数。自动外部   name与本地名称相同,就像您编写了一个哈希一样   代码中本地名称前面的符号。

所以你的第一个函数声明

func DoIt(a: Int, b: Int, c : Int = 0) -> Int

被编译器视为

func DoIt(a: Int, b: Int, c c : Int = 0) -> Int

使用外部参数名称" c"对于第三个参数。这个功能 必须被称为

DoIt(4, 5, c: 6)   // result: 15

但是电话

DoIt(4, 5, 6)

第一个函数的声明不匹配,只与其他函数的声明匹配

func DoIt(a: Int, b: Int, c :NSObject) -> Int

(第三个参数自动桥接到NSNumber,这是一个子类 NSObject)。这就是为什么你会得到意想不到的"输出

如果将第一个函数的声明更改为

func DoIt(a: Int, b: Int, _ c : Int = 0) -> Int

(其中_代表"没有外部参数名称") 然后你会得到预期的输出:

DoIt(4, 5, 6)   // result: 15