微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

我在操场上编写了用于测试(学习)目的的代码
import Cocoa
func DoIt(a: Int,b: Int,c :Int = 0) -> Int {
    return a + b + c;
}
func DoIt(a: Int,c :NSObject) -> Int {
    return a * b * c.description.lengthOfBytesUsingEncoding(NSUTF8StringEncoding);
}

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

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

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

奇怪的是,如果我需要最后一个c:Int(通过删除= 0),那么它按预期工作.

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

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

$swiftc \
   -emit-ir /Users/nacho4d/Desktop/function2/function2/main.swift \
   -sdk Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk
从Swift文档中的 “Functions”开始(强调添加):

External Names for Parameters with Default Values

In most cases,it is useful to provide (and therefore require) an
external name for any parameter with a default value. This ensures
that the argument for that parameter is clear in purpose if a value is
provided when the function is called.

To make this process easier,Swift provides an automatic external name
for any parameter that has a default value. The automatic external
name is the same as the local name,as if you had written a hash
symbol before the local name in your code.

所以你的第一个函数声明

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

被编译器视为

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

使用外部参数名称“c”表示第三个参数.这个功能
必须被称为

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

但是电话

DoIt(4,6)

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

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

(第三个参数自动桥接到NSNumber,它是一个子类
NSObject).这就是你得到“意外”输出的原因.

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

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

(其中_代表“无外部参数名称”)
然后你会得到预期的输出

DoIt(4,6)   // result: 15

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐