[英]Determine Protocol Conformance of Generic (Possibly Protocol) Type
即使在通用類型本身就是協議本身的情況下,在Swift中也可以檢查通用類型是否符合協議 ?
protocol Parent {}
protocol Child: Parent {}
struct ParentType: Parent {}
struct ChildType: Child {}
func generic<T>(possiblyParent: T?) {
if T.self is Parent.Type { //Only works for non-protocol types :(
print("Parameter conforms to Parent.")
}
}
let one: Parent? = nil
let two: Child? = nil
let three: ParentType? = nil
let four: ChildType? = nil
generic(one) //no, but I wish yes
generic(two) //no, but I wish yes
generic(three) //yes
generic(four) //yes
協議類型的元類型(不是在運行時符合協議的具體類型)是該協議的名稱,后跟
.Protocol
。 例如,類類型SomeClass
的元類型是SomeClass.Type
,協議SomeProtocol
是SomeProtocol.Protocol
。
將此應用於您的問題,您可以執行以下操作:
func generic<T>(possiblyParent: T?) {
guard let p = possiblyParent else { return }
// You could use an if statement instead of a switch here, if you wanted.
switch p.dynamicType {
case is Parent.Type, is Parent.Protocol:
print("Parameter conforms to Parent.")
default:
print("Parameter doesn't conform to Parent")
}
}
用法:
let one : Parent = ParentType()
let two : Child = ChildType()
let three: Parent = ChildType()
generic(one) // Prints: Parameter conforms to Parent.
generic(two) // Prints: Parameter conforms to Parent.
generic(three) // Prints: Parameter conforms to Parent.
generic("Hello") // Prints: Parameter doesn't conforms to Parent.
您可以嘗試使用標准的可選強制轉換:
func generic<T>(possiblyParent: T?) {
if let _ = possiblyParent as? Optional<Parent> {
print("Parameter conforms to Parent.")
}
}
在Swift 2.0 b3上,當您傳遞的可選參數不是nil
時,它似乎可以正常工作。
但不幸的是:
let someInt: Int? = 3 // no and it is correct
let nilInt: Int? = nil // yes, but it should be no
這可能是一個錯誤。 無論如何,如果possiblyParent
為零,通常您可以做的更多。
因此,如果您的目的是在不為空的情況下實際使用該參數,則可能更喜歡這樣的通用函數:
func generic<T>(possiblyParent: T?) {
if let p = possiblyParent, // parameter is not empty
let parent = p as? Parent // parameter content conforms to Parent {
print("parent can be safely used as a Parent.")
}
}
希望這可以幫助
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.