我想根據類型創建字符串(如果您必須知道的話,部分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 typeTestP
TestP.Type
和TestP.Protocol
也不作爲參數工作。
如何將協議類型傳遞給(通用)函數?
這並不是很好的理由 - 比如'TestP'有一個'static'要求。你可以在'toDescription'中調用'type'的要求 - 但是如果你能夠通過'TestQ.self',那麼就沒有實現可以調用。 – Hamish
這是一個更大限制的一部分(爲了防止這些不安全的情況,但是否則充滿了完全安全的邊緣情況),這就是[協議不符合自己](http:// stackoverflow .com/questions/33112559/protocol-doesnt-conform-to-itself) - 所以你不能使用'TestQ'作爲符合'TestP'的類型。 – Hamish
@Hamish我明白了。我想我希望能寫'func f(type:T.Protocol)',那麼在這種情況下,編譯器可以檢查我沒有在協議類型上調用靜態成員。 (好吧,即使在我編寫的版本中,它也可能阻止我訪問靜態成員,因爲它可能會失敗。) –
Raphael