Swift泛型和子类

bin*_*oan 2 arrays generics swift

我的问题可能很简单,但它让我感到困惑:想象一下,我有一组不同的对象,它们都有一个共同的父类" MyClass".

var values = [MyClass]()
Run Code Online (Sandbox Code Playgroud)

但是它们都有自己的特定子类,例如" MyClassSubclass".

values.append(MyClassSubclass())
Run Code Online (Sandbox Code Playgroud)

我现在想创建一个泛型方法,返回我在这个数组中的第一个对象MyClassSubclass.我想阻止转换对象,但是有一个泛型方法,它将子类对象作为T参数,并在此数组中返回第一次出现的子类T.

我想到了这样的事情(但肯定不行):

func getFirst<T: MyClass>(_ ofType : T.Type) -> T?
Run Code Online (Sandbox Code Playgroud)

我想我只是卡住了,我不知道该搜索什么,所以如果有人能帮助我,我会非常感激.

根据以上值编辑示例:

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?{}
Run Code Online (Sandbox Code Playgroud)

谢谢

Mar*_*n R 5

一种方法是迭代数组并使用可选绑定来检查元素是否属于给定类型:

func getFirst<T: MyClass>(ofType: T.Type) -> T? {
    for elem in values {
        if let item = elem as? T {
            return item
        }
    }
    return nil
}
Run Code Online (Sandbox Code Playgroud)

这可以使用被简化for caseas图案:

func getFirst<T: MyClass>(ofType: T.Type) -> T? {
    for case let item as T in values {
        return item
    }
    return nil
}
Run Code Online (Sandbox Code Playgroud)

另一种方法是使用flatMap查找给定类型的所有项目并返回第一个:

func getFirst<T: MyClass>(ofType: T.Type) -> T? {
    return values.flatMap { $0 as? T }.first
}
Run Code Online (Sandbox Code Playgroud)

如果数组可能很大并且您想避免创建中间数组,那么您可以使用lazy:

func getFirst<T: MyClass>(ofType: T.Type) -> T? {
    return values.lazy.flatMap { $0 as? T }.first
}
Run Code Online (Sandbox Code Playgroud)

作为数组扩展方法,这将是

extension Array {
    func getFirst<T>(ofType: T.Type) -> T? {
        return flatMap { $0 as? T }.first
    }
}
Run Code Online (Sandbox Code Playgroud)