Swift从元类型获取类型

时间:2019-05-16 12:44:10

标签: swift

如果您具有String.Type之类的快速元类型。在这种情况下,如何将其转换为类类型String

See the docs -元类型类型部分

2 个答案:

答案 0 :(得分:2)

假定一个NSManagedObject.Type的数组

var entities: [NSManagedObject.Type] {
    return [Entity1.self,
            Entity2.self]
}

for entity in entities {
    let fetchRequest: NSFetchRequest<NSFetchRequestResult> = entity.fetchRequest()
    do {
        let result = try managedObjectContext.fetch(fetchRequest)
        //do something with result
    } catch {
        print(error)
    }
}
}

我尝试了一个不同的版本,您需要以某种方式检查返回的内容并分别处理每个结果,因此这是我能得到的。这样可以编译并执行。

func fetchOne<T: NSManagedObject>(_ objectType: T.Type) throws -> [T]? {
    let fetchRequest: NSFetchRequest<NSFetchRequestResult> = objectType.fetchRequest()
    return try managedObjectContext.fetch(fetchRequest) as? [T]
}

func doFetchAll() {
    for entity in entities {
        let fetchRequest: NSFetchRequest<NSFetchRequestResult> = entity.fetchRequest()
        do {
            if let result = try fetchOne(entity) {
                if result is [InstrumentData] {
                    print(result[0].value(forKey: "name"))
                }
            }
        } catch {
            print(error)
        }
    }
}

答案 1 :(得分:1)

您不能从元类型转变为类型。

因为Swift是静态类型的,所以实际上只有两种情况。要么:

  1. 编译器知道您具有该元类型的类型,在这种情况下,您已经具有该类型并且不需要使用该元类型。
  2. 编译器不知道您具有哪种类型的元类型,在这种情况下,除了在运行时检查(可能会失败)之外,没有其他方法 来获取类型。

案例1看起来像这样。

let x = "foo"                 // inferred as String
let y = type(of: x)           // inferred as String.Type
let z: [String] = [y.init()]  // inferred as [String], so types match

编译器知道类型是什么,您也知道。无需从y返回到String,因为您可以直接键入String,并且编译器知道最新信息。

案例2就是这样。

class Base { required init() {} }
class A: Base {}
class B: Base {}

// compiler still knows all the types
let types = [A.self, B.self]

for type in types {
    // now all bets are off, everything is just Base
    switch type.init() {
    case let a as A:
        print(a)
    case let b as B:
        print(b)
    default: // you might end up here!
        print("no idea what it is")
    }
}

同样,我们不能从typeAB,因为编译器已经不知道类型是什么了。您只需要在运行时进行测试即可。