将类型传递给泛型函数并进行比较

时间:2014-12-30 20:21:09

标签: swift

考虑这个简单的例子

func contains<T>(type t: T.Type) -> Bool {
    for i in 0..<list.count {
        if list[i] is t { // compiler says: 't' is not a type
            return true
        }
    }
    return false
}

编译器以

响应
't' is not a type

由于我无法声明静态类型并使用is MyStaticType进行检查,我如何使用泛型在Swift中完成此操作?

2 个答案:

答案 0 :(得分:3)

您应该检查它是否T

if list[i] is T {
    ...
}

答案 1 :(得分:2)

那是因为t确实不是一种类型。它是Metatype类型的实例:

let x = NSString.self
// compiler error because the following is 
// always true but you get the idea...
x is NSString.Type

您只想检查T,这是实际类型,但可以使用T.Type来确定T的内容:

// genericised a bit, to make list an argument
func contains
  <S: SequenceType, T>
  (list: S, type t: T.Type) -> Bool {
    for element in list {
        if element is T {
            return true
        }
    }
    return false
}

let a = ["a","b","c"]
contains(a, type: String.self)    // true
contains(a, type: NSString.self)  // true
contains(a, type: Int.self)       // false
contains(a, type: NSNumber.self)  // false

let b: [Any] = [1, 2 as NSNumber, "c" as NSString]
contains(b, type: String.self)    // true
contains(b, type: NSString.self)  // true
contains(b, type: Int.self)       // true
contains(b, type: NSNumber.self)  // true

请记住T仍然在编译时静态确定,而不是动态确定。所以:

let c: NSObject = 1 as NSNumber
contains(a, type: c.dynamicType)

返回true 而非 false,因为它正在检查NSObject(因为c.dynamicType的结果类型为{{1}不是NSObject.Type)。