我在操场上编写了用于测试(学习)目的的代码:
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);
但显然正在调用另一个函数6
。 6
去了哪里?看起来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}}
答案 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