我的问题可能很简单,但它让我感到困惑:
想象一下,我有一系列不同的对象,它们都有一个共同的父类" MyClass
"。
var values = [MyClass]()
然而,他们都有自己的特定子类,例如" MyClassSubclass
"。
values.append(MyClassSubclass())
我现在想要创建一个泛型方法,让我返回此数组中第一个类型为MyClassSubclass
的对象。我想阻止转换对象,但是有一个泛型方法,它将子类对象作为T参数,并在此数组中返回第一次出现的子类T.
我想到了类似的东西(但肯定不起作用):
func getFirst<T: MyClass>(_ ofType : T.Type) -> T?
我想我只是被卡住而且我不知道该搜索什么,所以如果有人能帮助我,我会非常感激。
修改 基于以上值的示例:
class MyClass {}
class MyClassSubclass : MyClass {}
class MyClassSubclass2 : MyClass{}
var values = [MyClass]()
values.append(MyClassSubclass())
values.append(MyClassSubclass2())
//Return the first class element appearing here as a subclass type
func getFirst<T>(_ ofType : T.Type) -> T?{}
由于
答案 0 :(得分:5)
一种方法是遍历数组并使用可选绑定 检查元素是否属于给定类型:
func getFirst<T: MyClass>(ofType: T.Type) -> T? {
for elem in values {
if let item = elem as? T {
return item
}
}
return nil
}
使用for case
模式{/ 1}}可以简化此操作:
as
另一种方法是使用func getFirst<T: MyClass>(ofType: T.Type) -> T? {
for case let item as T in values {
return item
}
return nil
}
查找给定的所有项目
输入并返回第一个:
flatMap
如果数组可能很大并且您想避免创建
中间数组然后你可以使用func getFirst<T: MyClass>(ofType: T.Type) -> T? {
return values.flatMap { $0 as? T }.first
}
:
lazy
作为数组扩展方法,这将是
func getFirst<T: MyClass>(ofType: T.Type) -> T? {
return values.lazy.flatMap { $0 as? T }.first
}
答案 1 :(得分:1)
这有点像滥用泛型,但这是一个扩展:
extension Array where Element == MyClass {
func getFirst<T>(_ ofType: T.Type) -> T? {
return self.first(where: { ofType == type(of: $0) }) as? T
}
}
然后可以将该方法称为let first = values.getFirst(MyClassSubclass.self)
。
我个人更喜欢简单地为了清晰度而内联:
let first = values.first(where: { type(of: $0) == MyClassSubclass.self }) as? MyClassSubclass
答案 2 :(得分:1)
如果您想使用不推荐使用的全局功能,请尝试使用
func getFirst<T>(ofType: T.Type) -> T? where T: MyClass {
for value in values where value is T {
return value as? T
}
return nil
}
let first = getFirst(ofType: MyClassSubclass2.self)
对于Swift,第一个答案应该更好。