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閱讀 134,837評論 18 139
  • 函數參數的默認值 基本用法 在ES6之前,不能直接為函數的參數指定默認值,只能采用變通的方法。 上面代碼檢查函數l...
    呼呼哥閱讀 3,438評論 0 1
  • 感謝社區中各位的大力支持,譯者再次奉上一點點福利:阿里云產品券,享受所有官網優惠,并抽取幸運大獎:點擊這里領取 函...
    HetfieldJoe閱讀 1,570評論 2 12
  • 每次快到考試的時候,總會有新的文字出現在這里,因為我焦慮得雙手無處安放。除了紙筆就只剩下鍵盤能擒住我不聽使喚的雙手...
    Glozzzy閱讀 395評論 1 3
  • 今天雪如約而至,雖然說不上洋洋灑灑,也算的上漫天飄舞。開始時,雪花成片,羞羞澀澀的覆蓋在地面上,瞬間化為潮濕,沁入...
    b7a019f3cbb9閱讀 128評論 2 3