Swift 从元类型中快速获取类型

Swift 从元类型中快速获取类型,swift,Swift,如果您有一个swift元类型,比如String.type。如何将其转换为类类型,在本例中为String -元类型类型节假设NSManagedObject.Type的数组 var entities: [NSManagedObject.Type] { return [Entity1.self, Entity2.self] } for entity in entities { let fetchRequest: NSFetchRequest<NSFet

如果您有一个swift元类型,比如String.type。如何将其转换为类类型,在本例中为String


-元类型类型节

假设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)
        }
    }
}

不能从元类型转换为类型

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

编译器知道您拥有的元类型是什么类型,在这种情况下,您已经拥有了该类型,并且不需要使用该元类型。 编译器不知道您的元类型是什么类型,在这种情况下,除了在运行时进行检查之外,无法获取该类型,这可能会失败 案例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
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")
    }
}
编译器知道类型是什么,您也知道。不需要从y返回到String,因为您可以直接键入String,编译器知道发生了什么

案例2是这样的

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
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")
    }
}

同样,我们不能从类型转换为A或B,因为编译器已经不知道这些类型是什么了。您只需在运行时进行测试。

您试图解决的实际问题是什么?您是否正在尝试从某个类型的元类型初始化该类型的实例?此问题几分钟前是否已作为重复项结束?@Zsolt是唯一一个String类型的对象。类型是String.self。字符串类型的唯一内容是字符串实例。你说字符串是类类型是什么意思?请发布一些示例伪代码来说明您需要什么。let request:NSFetchRequest=class。fetchRequest@Zsolt那是因为你的问题不清楚。您需要在问题本身而不是在注释中澄清您试图解决的确切问题。是的,这很好,但如果您需要知道结果中的对象类型,则需要指定对象类型,如Entity1或Entity2。。如果你只有Entity1.Type,有没有办法做到这一点呢?我很确定结果数组的类型是[Entity1]default@JoakimDanielson绝对不是。若结果是Entity1或Entity2,则需要使用条件绑定在运行时进行测试。这只会编译,因为它将所有内容都转换为泛型NSManagedObject,因此您将丢失所有其他类型info@Max对,我在考虑NSFetchRequest=Enity1。fetchRequest@Max它不会丢失所有类型信息,将执行正确的获取请求