2017-02-28 84 views
0

我想根據類型創建字符串(如果您必須知道的話,部分URL)。如何將協議類型傳遞給泛型函數?

考慮該示例代碼:

import Foundation 


protocol TestP { 
    var p: Int { get } 
} 
protocol TestQ: TestP { 
    var q: Int { get } 
} 
struct TestR: TestQ { 
    var p = 1 
    var q = 2 
} 

func toDescription<T: TestP>(type: T.Type) -> String { 
    switch type { 
     case is TestR.Type: return "Arrrr" 
     default: return "unsupported" 
    } 
} 

這似乎相當不錯;我不需要依賴不安全的措施(字符串),也不需要單獨的枚舉。

讓我們看看一些使用例如:

func example1<T: TestP>(val: T) { 
    print("Processing \(toDescription(type: T.self))") 
} 

func example2() { 
    print("Processing \(toDescription(type: TestR.self))") 
} 

func example3() { 
    print("Processing \(toDescription(type: TestQ.self))") 
} 

雖然前兩個功能都很好(通用版特別好聽!),第三不編譯:

Error: in argument type TestQ.Protocol.Type , TestQ.Protocol does not conform to expected type TestP

TestP.TypeTestP.Protocol也不作爲參數工作。

如何將協議類型傳遞給(通用)函數?

+1

這並不是很好的理由 - 比如'TestP'有一個'static'要求。你可以在'toDescription'中調用'type'的要求 - 但是如果你能夠通過'TestQ.self',那麼就沒有實現可以調用。 – Hamish

+0

這是一個更大限制的一部分(爲了防止這些不安全的情況,但是否則充滿了完全安全的邊緣情況),這就是[協議不符合自己](http:// stackoverflow .com/questions/33112559/protocol-doesnt-conform-to-itself) - 所以你不能使用'TestQ'作爲符合'TestP'的類型。 – Hamish

+0

@Hamish我明白了。我想我希望能寫'func f (type:T.Protocol)',那麼在這種情況下,編譯器可以檢查我沒有在協議類型上調用靜態成員。 (好吧,即使在我編寫的版本中,它也可能阻止我訪問靜態成員,因爲它可能會失敗。) – Raphael

回答

-2
protocol TestP { 
    var p: Int { get } 
} 
protocol TestQ: TestP { 
    var q: Int { get } 
} 
struct TestR: TestQ { 
    var p = 1 
    var q = 2 
} 

struct TestS: TestP 
{ 
    var p = 42 
} 

func toDescription<T: TestP>(type: T.Type) -> String 
{ 
    switch type 
    { 
    case let x where x == TestR.self: 
     return "Arrr" 
    default: 
     return "Unsupported" 
    } 
} 

print (toDescription(type: TestR.self)) // Arrr 
print (toDescription(type: TestS.self)) // Unsupported 
+1

這沒有解決OP所具有的問題。 OP正試圖將'TestQ.self'傳遞給'toDescription(type:)',但它會產生編譯器錯誤。 – Hamish

+2

此外,僅有代碼的答案很少提供很多洞見,因爲缺乏解釋。 – Raphael

相關問題