代码之家  ›  专栏  ›  技术社区  ›  Piepants

能否将对象的类型传递给函数?

  •  0
  • Piepants  · 技术社区  · 7 年前

    我有一系列不同类型的视图控制器。我希望能够检查数组是否包含各种类型。 换句话说,是否有任何方法可以简化以下代码

    for item in theArray
    {
       if item is ViewControllerTypeA
       {
         ...
       }
    }
    for item in theArray
    {
       if item is ViewControllerTypeB
       {
         ....
       }
    }
    for item in theArray
    {
       if item is ViewControllerTypeC
       {
         ....
       }
    }
    

    func doesArrayContainType(T)
    {
        for item in theArray
       {
           if item is T
           {
            ....
           }
       }
    }
    

    有没有什么方法可以使用泛型?如果是这样的话,那么关于泛型的非教程或参考对我所看到的这种特殊情况有任何帮助。

    2 回复  |  直到 7 年前
        1
  •  1
  •   Cristik    7 年前

    是的,您可以将类型信息传递给方法

    extension Sequence {
        // gives you an array of elements that have the specified type
        func filterByType<T>(_ type: T.Type = T.self) -> [T] {
            return flatMap { $0 as? T }
        }
    }
    

    上述函数将为您提供目标序列中与要搜索的类型匹配的元素列表。

    您可以使用它,也可以不使用 type 参数,前提是编译器可以推断结果类型:

    let mixedArray: [Any] = [1, "2", 3, "4"]
    
    // you need to pass the `type` parameter
    mixedArray.filterByType(Int.self) // [1, 3]
    
    // you don't need to pass the `type` parameter as the compiler
    // can infer T by looking at the sorounding context
    let strings: [String] = mixedArray.filterByType() // ["2", "4"]
    
        2
  •  0
  •   Callam    7 年前

    这里有三个不同的控制器。

    class AViewController: UIViewController {}
    class BViewController: UIViewController {}
    class CViewController: UIViewController {}
    

    和一个函数,该函数接受一个文件夹数组和一个类型数组。

    func arrayOf<T: UIViewController>(_ array: [T], containsTypes types: [T.Type]) -> Bool {
        return array.contains { vc in types.contains { $0 === type(of: vc) as T.Type } }
    }
    

    该函数检查控制器的类型是否包含在给定的类型数组中。如果至少有一个类型存在,它将返回true。

    let controllers = [
        AViewController(),
        BViewController(),
        CViewController()
    ]
    
    print(arrayOf(controllers, containsTypes: [ AViewController.self, BViewController.self ]))
    print(arrayOf(controllers, containsTypes: [ CViewController.self ]))