假设我有一些父类型的数组或向量。要将其传递给函数,我需要将其设置为某种子类型(我事先知道所有元素都必须保证是该子类型)。有方便的方法吗?现在,我只能考虑制作一个全新的阵列。
同样,它看起来也不允许我这样做:它不会在父类型的位置接受子类型的数组。是否有解决此问题的好方法?
看起来cast v不错,但这是首选方式吗?
要将其传递给函数,我需要将其设置为某种子类型(我事先知道所有元素都必须保证是该子类型)。
如果您确实有把握,可以使用cast。我不认为有这样做的任何漂亮的方式,也不应该有,因为它本质上是不漂亮。必须执行此操作通常表明您的代码或正在使用的API中存在设计缺陷。
对于相反的情况,了解为什么它不安全会很有帮助。由于这种思考过程,其原因不一定像直观的那样:
我可以分配
Child给我Base,为什么我不能分配Array<Child>给Array<Base>?
该确切示例用于解释Haxe手册中的方差 。您绝对应该完整阅读它,但是在这里我将给出一个简短的摘要:
var children = [new Child()];
var bases:Array<Base> = cast children;
bases.push(new OtherChild());
children[1].childMethod(); // runtime crash
Run Code Online (Sandbox Code Playgroud)
如果可以将分配Array<Child>给Array<Base>,则可以输入与其push()不兼容的类型Child。但是,正如您提到的,您可以再次使用cast它来使编译器静音,如上面的代码片段所示。
但是,这并不总是安全的-可能仍然有代码保存对该原始文件的引用Array<Child>,该文件现在突然包含了它不希望的内容!这意味着我们可以执行类似调用childMethod()没有该方法的对象的操作,并导致运行时崩溃。
反之亦然,如果没有代码保留此类引用(或者如果引用是只读的,例如via haxe.ds.ReadOnlyArray),则可以安全地使用cast。
归根结底,这是在制作副本的性能成本(根据大小可能可以忽略不计)与您对自己比编译器更聪明/对存在的所有引用有所了解的信心之间做出的权衡。