2015-12-03 69 views
2

這是我在StackOverflow上的第一個問題,所以請對我輕鬆點。Swift Type Inference Not Working(Xcode 7.1.1)

我一直在努力讓Swift調用適當的泛型重載。

假設我有以下協議 -

protocol MyProtocol { } 

而且我有以下的通用方法 -

func foo<T>() -> T 

func foo<T: MyProtocol>() -> T 

人們預計,隨着T符合MyProtocol返回類型調用foo()將調用適當的過載。

let bar: MyProtocol = foo() 

上面的代碼實際上在運行期間調用下面的函數和Cmd的+點擊IDE導航到錯誤的過載,以及。

func foo<T>() -> T 

出於某種原因,我不能得到這個在Xcode 7.1.1正常工作。

我是否錯過了一些完全基礎的東西,或者這是另一個Swift怪癖?

編輯

添加的這種行爲在行動按馬特的請求的示例。

protocol MyProtocol { } 

class MyProtoClass : MyProtocol { } 

class Bar { 

    func foo<T>(value: T) { 
     print("T is Generic") 
    } 

    func foo(value: MyProtocol) { 
     print("T conforms to MyProtocol") 
    } 
} 

class MyClass<T> { 

    var value: T 
    init(value: T) { self.value = value } 
    var b = Bar() 

    func print() { 
     b.foo(value) 
    } 
} 

MyClass<MyProtocol>(value: MyProtoClass()).print() 
MyClass<String>(value: "").print() 

將上面的代碼複製並粘貼到Swift命令行應用程序中,並執行以下輸出。

T is Generic 
T is Generic 
+1

請問您能否顯示用於測試的實際代碼?一個好的SO問題應該包含複製,粘貼和運行在自己機器上的一切。 – matt

+0

謝謝你的建議,亞光。我已經添加了代碼來重現此行爲。 – Randy

+0

非常酷,謝謝你這樣做。 – matt

回答

0

好了,我要在這裏回答我的問題。

經過一番調查後,似乎Swift希望你實現一個帶泛型參數類型約束的擴展。

extension MyClass where T : MyProtocol { 
    func print() { 
     b.foo(value) 
    } 
} 

我知道這並不能真正解決問題,但它是足夠的足以讓我在我的現實世界中的用例周圍的工作。

上面的示例看起來像下面這樣。

protocol MyProtocol { } 

class MyProtoClass : MyProtocol { } 

class Bar { 

    func foo<T>(value: T) { 
     print("T is Generic") 
    } 

    func foo(value: MyProtocol) { 
     print("T conforms to MyProtocol") 
    } 
} 

class MyClass<T> { 

    var value: T 
    init(value: T) { self.value = value } 
    var b = Bar() 

    func print() { 
     b.foo(value) 
    } 
} 

extension MyClass where T : MyProtocol { 

    func print() { 
     b.foo(value) 
    } 
} 

MyClass<MyProtoClass>(value: MyProtoClass()).print() 
MyClass<String>(value: "").print() 
1

我覺得這裏的問題是,協議中的泛型(一般在SWIFT)不工作,你希望他們的方式。他們不是一流的類型。我知道這很模糊......但是這樣看,如果您消除foofunc foo<T>(value: T)版本,則您的代碼甚至不會編譯。換句話說,Swift不會選擇foo並選擇錯誤;它的意思是b.foo(a1.value)不會撥打func foo<T: MyProtocol>(value: T)

我有一個模糊的感覺,這是涉及到我這裏的問題:

Protocol doesn't conform to itself?

+0

通過你的SO帖子閱讀,似乎有什麼東西在斯威夫特失蹤。如果我將MyProtoClass()或「」直接傳遞給foo(),則會調用適當的過載。當泛型類型以另一種類型包裝時,編譯器不會識別該類型符合MyProtocol。 – Randy

+0

我知道我的答案不是很好。如果你提出一個更好的表述,你應該回答你自己的問題(你甚至可以接受你自己的答案,我可能會贊成它!)。 – matt

+0

我很欣賞馬特的反饋。在這一點上,我感覺Swift真的處於起步階段,類型系統正在進行中。如果我能找到一個解決方法,那麼我會接受這是一個可行的答案,因爲Swift根本就不存在。 – Randy