2015-06-03 48 views
-2

我有一個快捷函數,我們稱之爲functionMakingMeUnhappyfunctionMakingMeUnhappy返回類型T其中TSomeProtocol類型。函數不接受給定的參數匹配定義

的定義是這樣的:

func functionMakingMeUnhappy<T:SomeProtocol>(meta: Metadata, value: Any, name: String) -> T 
{ 
    // Do some stuff and then return something as! T 
    return returnSomeStuff(meta, value: value, name: name) as! T 
} 

如果沒有任何用處的,元數據是看起來像這樣的結構:

public struct Metadata 
{ 
    var someUniqueIdentifier: String 
    var someOtherUniqueIdentifier: String 
    var someTypeIdentifier: String 
    var somePermission: String 

    var someOtherProperties = [String: Any]() 

    init(someUniqueIdentifier: String, 
     someOtherUniqueIdentifier: String, 
     someTypeIdentifier: String, 
     somePermission: String, 
     someOtherProperties: [String: AnyObject]) 
    { 
     self.someUniqueIdentifier = someUniqueIdentifier 
     self.someOtherUniqueIdentifier = someOtherUniqueIdentifier 
     self.someTypeIdentifier = someTypeIdentifier 
     self.somePermission = somePermission 
     self.someOtherProperties = someOtherProperties 
    } 
} 

現在,我的問題,因爲愚蠢的,因爲它可能聲音,當我調用functionMakingMeUnhappy具有完全相同的參數類型作爲函數定義時,我得到一個錯誤,說不能調用functionMakingMeUnhappy類型的參數列表(元數據,值:任何,名稱:字符串)'

的調用如下:

var data = Metadata(someUniqueIdentifier: "id", 
    someOtherUniqueIdentifier: "charType", 
    someTypeIdentifier: "type", 
    somePermission: "readonly", 
    someOtherProperties: [:] 
) 
var unhappy = functionMakingMeUnhappy(data, value: "someValue", name: "someName") 

有一個通用的功能,可能是這個錯誤的原因時,有沒有什麼要求?

+2

T應該如何解決? (並且,繼續這個想法,爲什麼這是一個通用的呢?) – matt

+0

@matt因爲我發現關於「協議只能用作通用約束的工作,因爲它具有自我或相關類型要求」 –

+0

你還在想我的問題嗎? T應該如何解決? – matt

回答

1

這聽起來像是你不明白什麼是通用的。儘管有這個名稱,泛型並不是通用的 - 它們不是某種魔術般的全部。相反,泛型是在編譯時必須知道的類型。這被稱爲分辨率(或規範)。

那麼,你打電話給functionMakingMeUnhappy的任何東西都無法解決這個問題。考慮你的代碼的下面非常簡化的版本:

protocol P{} 
class C:P{} 
func f<T:P>() -> T { 
    return C() as! T 
} 
var v = f() // error 

沒有任何關於調用f()會告訴編譯T是。因此它不會編譯。我承認錯誤信息是誤導性的,但事實上這是錯誤的。 T只出現在返回類型中。但是你沒有說什麼關於返回類型。

現在這樣來做:

protocol P{} 
class C:P{} 
func f<T:P>() -> T { 
    return C() as! T 
} 
var v : C = f() // ok 

,編譯。爲什麼?因爲現在我們已經做了一些事情來告訴編譯器返回類型f將是什麼。因此T得到解決。

(且如圖所示 請注意,我還沒有接觸,以爲什麼你已經做出了通用的。我只是回答你問直接的問題,即:爲什麼你的代碼的功能時,您離奇索賠, ,不編譯。)

+0

泛型被使用的唯一原因是因爲我想要一種方法來返回SomeProtocol。由於我無法控制SomeProtocol實現,因此修復第一個錯誤「Protocol只能用作通用約束是因爲它具有Self或相關類型要求」是我最初關心的問題 –

+0

是的,但請參閱上面的註釋。如果這是問題,你應該對此有所瞭解。相反,你問了這個 - 我告訴你答案。我已經解釋了編譯錯誤的來源。事實上,你完全走錯了路是另一回事。 – matt

+0

您的時間非常感謝,您根據我提供的信息正確回答。下次嘗試更具體。 –