2017-10-07 44 views
3

我的印象是,swift可能重載的方法僅在方法返回的對象類型上有所不同。我認爲我可以使用兩個具有相同簽名的funcs,但它們在返回類型上有所不同。重載方法,其中只有差異是可選與非可選類型

import Foundation 

// ambiguous use of 'IsTextEmpty(text:)' 
func IsTextEmpty(text : String?) -> Bool? { 
    return text?.isEmpty 
} 

func IsTextEmpty(text : String?) -> Bool { 
    guard let text = text else { 
    return true 
    } 

    return text.isEmpty 
} 

let text: String? = nil 

if let empty = IsTextEmpty(text:"text") { 
    print("Not Empty") 
} 

if IsTextEmpty(text: text) { 
    print("Empty") 
} 

在這裏,這兩個函數具有相同的輸入參數,但一個FUNC返回一個可選Bool?,另一個返回一個Bool。在這種情況下,我得到一個錯誤:

ambiguous use of 'IsTextEmpty(text:)' 

如果我改變了一個輸入參數的名字,我不再得到明確的錯誤:

// Works 
func IsTextEmpty(foo : String?) -> Bool? { 
    return foo?.isEmpty 
} 

func IsTextEmpty(text : String?) -> Bool { 
    guard let text = text else { 
    return true 
    } 

    return text.isEmpty 
} 

let text: String? = nil 

if let empty = IsTextEmpty(foo:"text") { 
    print("Not Empty") 
} 

if IsTextEmpty(text: text) { 
    print("Empty") 
} 

不應該編譯器檢測到它們是兩種截然不同的方法,即使它們的返回類型不同,因爲可選Bool?與非可選Bool是不同的類型?

+1

在同一方法名的情況下,只有返回類型不同,編譯器韓元無法區分。正如你可以讓'abc = IsTextEmpty(text:「text」)'爲可選返回和非可選返回。你如何看待,編譯器將能夠挑選出一種方法。 – Aks

回答

1

編譯器需要一些上下文來決定調用哪個方法,例如,

let e1 = IsTextEmpty(text: text) as Bool 
let e2: Bool = IsTextEmpty(text: text) 

調用非可選的變體,或

let e3 = IsTextEmpty(text: text) as Bool? 
let e4: Bool? = IsTextEmpty(text: text) 

調用可選的變種。現在

if IsTextEmpty(text: text) { 
    print("Empty") 
} 

編譯沒有問題:if語句需要一個boolean表達式 ,所以這裏沒有歧義。

但顯然,編譯器是不夠聰明弄清楚, 在任選的結合在右手側的表達式的上下文必須一些可選 並自動推斷展開的類型。

你需要明確標註的empty類型:

if let empty: Bool = IsTextEmpty(text: text) { ... } 

或使返回類型明確:

if let empty = (IsTextEmpty(text: text) as Bool?) { ... } 
+0

編譯器是否無法在此上下文中推斷可選綁定中的rhs,這對於錯誤報告可能是可行的?爲了清楚起見,我們可以研究相關的模式匹配和綁定形式(相同的歧義錯誤),並注意'如果大小寫.some(empty)= IsTextEmpty(text:「text」){/ * ... * /}'如果'IsTextEmpty(text:)'是一個單一的重載,返回一個非可選的(_「錯誤:模式不能匹配'Bool''」_)類型的值,將無法編譯。我希望編譯器能夠推斷實際上有效/編譯的唯一重載的用法(這裏沒有類似SFINAE的操作?:))。 – dfri

+1

@dfri:是的,如果只有一個函數返回一個非可選項,那麼'if let empty = IsTextEmpty(foo:「text」)'也會失敗,所以有一個可能的選擇。我*猜測*是編譯器不能解決RHS作爲「返回一個可選的東西」而不知道未包裝的類型,但我不熟悉編譯器的內部工作原理。 - 提交錯誤報告不會受到傷害,也許可以改進,或者蘋果工程師解釋爲什麼無法完成。 –

+1

是的,這聽起來似乎合理。 [這裏有一些更簡單的例子](https://gist.github.com/anonymous/7eff7ba0584f295464805db8161a9491)推斷失敗(以及在使用上述兩種解決方法時的非失敗,即使這些都是有效的,可選返回,以防止這是唯一的過載)。 – dfri

相關問題