我想在运行时定义一个临时类(目标是创建用于测试的模拟对象)。例如:
class Foo {
func bar(classType) {
class Mock: classType {
// class body
}
let m = Mock()
...
}
}
目前可以在Swift中做这样的事吗?如果不是直接,也许是通过泛型?
答案 0 :(得分:4)
这听起来像Ruby中可能做的事情。但Swift与Ruby相反:每种类型都必须在编译时完全定义。
如果在编译时已知classType
,那么您的代码肯定是合法的:在函数中定义类没有任何问题(当然,当函数的其余部分运行时,它只在范围内)。但是在编译时必须很好地定义该类的超类;它不能推迟到运行时间。
答案 1 :(得分:1)
是和否;或许,不,是的。
正如@ matt的答案所述,Swift打字非常静态。 Swift中存在一个泛型系统并没有改变这一点:所有输入仍然是静态的,因为它在编译时是已知的,例如,当你使用泛型时T
正在使用例如func foo<T>(t: T)
或创建Array<T>
。 编译器必须具有创建子类的类知识,因此您无法在那里使用动态运行时信息。 (即使可以对泛型类型参数进行子类化,也必须对该参数进行约束,以便为编译器提供可能超类的静态知识。)
然而,Swift使用Objective-C运行时并与之互操作(在Apple平台上;对不起,开源的Swift-on-Linux-etc用户)。因此,您可以使用ObjC Runtime APIs到create classes并使用方法和属性在运行时根据仅在运行时提供的知识对其进行填充。从理论上讲,你甚至可以使用那些API和Swift代码生成的类......当然,它不会很漂亮,因为根据定义,你的Swift代码在编译时不会为动态创建静态类型信息类。