是否可以在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
答案 0 :(得分:0)
来自The Swift Programming Guide: Types:
协议类型的元类型 - 不符合的具体类型 运行时的协议 - 是后面的协议的名称
.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.
答案 1 :(得分:0)
您可以尝试使用标准的可选演员:
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.")
}
}
希望这有帮助