我知道标题令人困惑,但我找不到更好的方法来压缩它:我有一个泛型函数,需要检查它收到的泛型类是属于类的泛型类型还是其他类型的类,而不知道泛型类的最终参数。这是我试图解决的示例:
public class GenericClass<T: Codable>: SomeProtocol {
var data: T?
init(data: T) {
self.data = data
}
}
public class LessGenericClass: SomeProtocol {
var specific: String?
init(specific: String) {
self.specific = specific
}
}
public func foo<T: SomeProtocol>(caller: T) {
if (caller as? GenericClass) != nil { /* do something */ } // --->>> THIS IS THE CRITICAL PART
if (caller as? LessGenericClass) != nil { /* do something else */ }
}
我遇到的问题是编译器期望在函数 foo 中解析 GenericClass。 在上面的代码中,错误将是:"无法在强制转换为"泛型类"时推断泛型参数'T'"。 例如,这将起作用:
public func foo<T: SomeProtocol>(caller: T, completion: @escaping(T.returnType?) -> () ) {
if (caller as? GenericClass<String>) != nil { /* do something */ } //
if (caller as? LessGenericClass) != nil { /* do something else */ }
}
但是,如果我必须声明我可以传递给 foo 函数的每个类型,它将违背使用泛型的目的。 任何帮助将不胜感激
这种运行时检查非常不迅速。
一种更快捷的方法是添加doSomething
作为协议要求
protocol SomeProtocol {
func doSomething()
// other stuff
}
public func foo<T: SomeProtocol>(caller: T, completion: @escaping(T.returnType?) -> ()) {
caller.doSomething()
}
即使你能够做到这一点,检查传递的参数是否是一组可能无限的泛型类型的一部分,你将如何检查泛型参数?
如果你不关心泛型参数,并且只想找出参数是否是GenericClass
,你可以做一些字符串编程:
if "(T.self)".hasPrefix("GenericClass<") { /* do your critical stuff */ }
请注意,这很容易出错,就像重命名类一样,您还必须保持字符串更新。