泛型函数,用于检查收到的泛型类是否为泛型类型



我知道标题令人困惑,但我找不到更好的方法来压缩它:我有一个泛型函数,需要检查它收到的泛型类是属于类的泛型类型还是其他类型的类,而不知道泛型类的最终参数。这是我试图解决的示例:

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 */ }

请注意,这很容易出错,就像重命名类一样,您还必须保持字符串更新。

最新更新