Swift 函数默认值的猜测

一. 在swift函数的申明语法中,可以给参数设置默认值,代码如下:

func test(name: String = "") {
    print(#function)
}
test() /// 调用一
test(name: "tom") /// 调用二
  • 有默认值的函数,可以省略参数的传递 调用一
  • 按正常函数调用 调用二

二. 这种函数是怎么实现的呢?

猜测:编译器会对应生成多个函数:

func test(name: String) {
    /// -> 相当于1种写法
    /// test(name: String)
    print(#function)
}
func test(name: String, address: String = "") {
    /// -> 相当于2种写法
    /// test(name: String)
    /// test(name: String, address: String)
    print(#function)
}

从上面的函数来看 test(name: String) 就被重复申明了,那么应该报错啊!不不不,我们只能说它可能报错,请看下面的代码,代码比较长,请耐心阅读

  • 正确情况:
/// 同名不同参
func test(name: String) {
    /// -> 相当于1种写法
    /// test(name: String) -> 和自身行式一样的,假设为特殊,可以覆盖其他(不能被其它覆盖)specialFunc
    print(#function)
}
func test(name: String, address: String = "") {
    /// -> 相当于2种写法
    /// test(name: String)
    /// test(name: String, address: String) specialFunc
    print(#function)
}
func test(name: String, age: Int = 18) {
    /// -> 相当于2种写法
    /// test(name: String)
    /// test(name: String, age: Int) specialFunc
    print(#function)
}
func test(name: String, age: Int = 18, address: String = "") {
    /// -> 相当于4种写法
    /// test(name: String)
    /// test(name: String, age: Int)
    /// test(name: String, address: String)
    /// test(name: String, age: Int, address: String) specialFunc
    print(#function)
}

/// 由于specialFunc的覆盖和唯一性
/// 上面的函数最终得到如下4个(仅有)唯一函数
/// test(name: String) specialFunc
/// test(name: String, address: String) specialFunc
/// test(name: String, age: Int) specialFunc
/// test(name: String, age: Int, address: String) specialFunc

/// 这里的调用一一对应specialFunc函数, 没有歧义,运行正常
test(name: "tom") /// test(name:)
test(name: "tom", address: "") /// test(name:address:)
test(name: "tom", age: 10) /// test(name:age:)
test(name: "tom", age: 10, address: "") /// test(name:age:address:)
  • 会产生错误的情况如下:
func parameter(name: String, address: String = "", age: Int = 18) {
    /// -> 相当于4种写法
    /// parameter(name: String)
    /// parameter(name: String, address: String)
    /// parameter(name: String, age: Int)
    /// parameter(name: String, address: String, age: Int) specialFunc
    print(#function)
}
func parameter(name: String, age: Int = 18, address: String = "") {
    /// -> 相当于4种写法
    /// parameter(name: String)
    /// parameter(name: String, age: Int)
    /// parameter(name: String, address: String)
    /// parameter(name: String, age: Int, address: String) specialFunc
    print(#function)
}

/// 上面的到6个有歧义的函数:
/// parameter(name: String)
/// parameter(name: String, address: String)
/// parameter(name: String, age: Int)
/// 和
/// parameter(name: String)
/// parameter(name: String, age: Int)
/// parameter(name: String, address: String)

/// 无法确认函数的唯一性,无法正确的调用函数,报错!
/// parameter(name: "")
/// parameter(name: "", age: 10)
/// parameter(name: "", address: "")

/// 上面的函数得到两个唯一函数:
/// parameter(name: String, address: String, age: Int) specialFunc
/// parameter(name: String, age: Int, address: String) specialFunc
/// 调用唯一函数,正确
parameter(name: "", address: "", age: 18)
parameter(name: "", age: 18, address: "")
  • 如上的代码可以直接运行来校验猜测
  • 就specialFunc而言,确实是出于对结果的构想(假定就是这样来推断后面的结果)

三. 以上是我个人的猜测。如有更好的解释,请各位多多指教。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,314评论 19 139
  • 函数参数的默认值 基本用法 在ES6之前,不能直接为函数的参数指定默认值,只能采用变通的方法。 上面代码检查函数l...
    呼呼哥阅读 8,851评论 0 1
  • 感谢社区中各位的大力支持,译者再次奉上一点点福利:阿里云产品券,享受所有官网优惠,并抽取幸运大奖:点击这里领取 函...
    HetfieldJoe阅读 5,433评论 2 12
  • 每次快到考试的时候,总会有新的文字出现在这里,因为我焦虑得双手无处安放。除了纸笔就只剩下键盘能擒住我不听使唤的双手...
    Glozzzy阅读 2,924评论 1 3
  • 今天雪如约而至,虽然说不上洋洋洒洒,也算的上漫天飘舞。开始时,雪花成片,羞羞涩涩的覆盖在地面上,瞬间化为潮湿,沁入...
    b7a019f3cbb9阅读 851评论 2 3