如何将Haxe数组/向量转换为另一种类型

log*_*s16 3 haxe

假设我有一些父类型的数组或向量。要将其传递给函数,我需要将其设置为某种子类型(我事先知道所有元素都必须保证是该子类型)。有方便的方法吗?现在,我只能考虑制作一个全新的阵列。

同样,它看起来也不允许我这样做:它不会在父类型的位置接受子类型的数组。是否有解决此问题的好方法?

看起来cast v不错,但这是首选方式吗?

Gam*_*a11 6

要将其传递给函数,我需要将其设置为某种子类型(我事先知道所有元素都必须保证是该子类型)。

如果您确实有把握,可以使用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


归根结底,这是在制作副本的性能成本(根据大小可能可以忽略不计)与您对自己比编译器更聪明/对存在的所有引用有所了解的信心之间做出的权衡。