Swift Generic 类型在运行时首先已知

Art*_*ann 5 generics runtime swift

我有一个关于 swift 和泛型的问题。我试图做的是获得一个具有泛型类型的对象。但我首先知道运行时的类型。但要快速切入正题。

新编辑的块:

也许我可以用班级名称做到这一点?我有一个类名作为字符串。我是通过镜子得到的。我可以在字符串中使用该类名创建一个通用实例吗?

let classname: String = "ClassA"
let firstA: a<classname> = a<classname>()
//            ^^^^^^^^^      ^^^^^^^^^
//            what to put here???          
Run Code Online (Sandbox Code Playgroud)

新编辑的块结束:

我有两个具有泛型类型的类:

这是我的类型必须实现的协议:

protocol ToImplement {
    func getTypeForKey(key: String) -> NSObject.Type
}
Run Code Online (Sandbox Code Playgroud)

这是我用于我的第一个通用类型的类:

class MyClass: ToImplement {
    func getTypeForKey(key: String) -> NSObject.Type {
        if key == "key1" {
            return UIView.self
        } 
        else {
            return UIButton.self
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我的第一个具有泛型类型的类:

class a<T:ToImplement> {
    func doSomethingWith(obj: T) -> T {

        // the next part usually runs in an iteration and there can be
        // a lot of different types from the getTypeForKey and the number
        // of types is not known

        let type = obj.getTypeForKey("key1")
        let newA: a<type> = a<type>()       // how could I do this? To create a type I do not know at the moment because it is a return value of the Object obj?
        //          ^^^^      ^^^^
        //          what to put here???


        return obj
    }
}
Run Code Online (Sandbox Code Playgroud)

这就是我将如何使用它:

let mycls: MyClass = MyClass()
let firstA: a<MyClass> = a<MyClass>()
firstA.doSomethingWith(mycls)
Run Code Online (Sandbox Code Playgroud)

现在我的问题是:我可以使用作为函数返回值的泛型类型创建类 a 的实例吗?这甚至可能吗?

如果这是不可能的,我怎么能从另一个实例中创建一个具有泛型类型的实例。就像是:

let someA: a<instance.type> = a<instance.type>()
Run Code Online (Sandbox Code Playgroud)

感谢您的帮助!

问候

阿图尔

jtb*_*des 1

let type = obj.getType
Run Code Online (Sandbox Code Playgroud)

好的,typea 也是如此NSObject.Type。由于 NSObject 提供了init(),你可以实例化这个类型

let obj = type.init()  // obj is a NSObject (or subclass)
return obj
Run Code Online (Sandbox Code Playgroud)

当然,如果返回的实际类型没有getType()实现,这将在运行时失败init()

另一种选择是使用关联类型:

protocol ToImplement {
    typealias ObjType: NSObject
}
Run Code Online (Sandbox Code Playgroud)

然后你可以将它用作通用约束:

func makeAnObject<T: ToImplement>(obj: T) -> T.ObjType {
    return T.ObjType()
}
Run Code Online (Sandbox Code Playgroud)

这给出了基本相同的结果。