2016-04-18 68 views
0

下面您會看到一個遊樂場,我試圖說明我的問題。我有一個類(Foo),其中一些重載的泛型方法(bar<T>())的返回類型取決於泛型參數。我有3種方法:當在Swift中重載泛型函數時,「Ambiguos使用函數」

  • 一個必須返回一個特定類型的子類(在下面的例子中它被稱爲BaseClass
  • 其他人必須返回此特定類型的實例的Array
  • 如果不滿足其他兩個條件,則最後一個應該用作默認值。

問題來了,當我打電話的方法。即使我告訴編譯器我期待的類型是什麼,它給我錯誤Ambiguos使用bar()

import UIKit 

class BaseClass { 
    required init() {} 
} 

class Foo { 

    // 1 
    func bar<T: BaseClass>() -> T? { 
     // Just a default implementation, it should do real work inside 
     return T() 
    } 

    // 2 
    func bar<T: BaseClass>() -> [T]? { 
     // Just a default implementation, it should do real work inside 
     return [] 
    } 

    // 3 
    func bar<T>() -> T? { 
     // Just a default implementation, it should do real work inside 
     return "Test" as? T 
    } 
} 

let foo = Foo() 

// Should call "1", because it return type is BaseClass 
let baseClassObject: BaseClass? = foo.bar() 

// Should call "2", because it return type is [BaseClass] 
let baseClasArray: [BaseClass]? = foo.bar() 

// Should call "3", because it return type is neither BaseClass nor [BaseClass] 
let anyOtherObject: String = foo.bar() 

在我看來,編譯器應該知道什麼方法調用,因爲我告訴它的返回類型,對不對?這是泛型的一個限制還是我錯過了什麼?

在此先感謝。

更新4月19日

在他們說了,他說的矛盾來,因爲「BaseClass的」可以被解釋爲BaseClass而且作爲T。但在這個修改後的遊樂場中,編譯器確實推斷出哪種方法正確使用。有什麼區別嗎?我這裏有同樣的衝突?:

import UIKit 

class BaseClass { 
    required init() {} 
} 

class Foo { 

    // 1 
    func bar<T: BaseClass>(param: T) -> String { 
     return "I am BaseClass" 
    } 

    // 2 
    func bar<T: BaseClass>(param: [T]) -> String { 
     return "I am [BaseClass]" 
    } 

    // 3 
    func bar<T>(param: T) -> String { 
     return "I am other thing" 
    } 
} 

let foo = Foo() 

// It prints "I am BaseClass" 
foo.bar(BaseClass()) 

// It prints "I am [BaseClass]" 
foo.bar([BaseClass(), BaseClass()]) 

// It prints "I am another thing" 
foo.bar(NSObject()) 

回答

2

號碼與其他功能

這是因爲< T>也可能是類型的BaseClass的和類型[BaseClass的]的3個起因衝突。編譯器只是看到一個「在這裏拋出任何東西」的接口,這將與任何更具體的特定級別相沖突。

+0

爲了擴大這個,爲什麼要'let baseClassObject:BaseClass? = foo.bar()'自動調用第一個'bar'? – BallpointBen

+0

是的,我知道衝突來自最後一個。我認爲編譯器知道我正在調用第一個,因爲返回類型。我認爲編譯器會從更具體到更具體的方面進行檢查,並使用更具體的方法。至少,在其他情況下它是這樣做的。請@PEEJWEEJ查看我的問題更新。 – manueGE