如何将Haxe数组/向量转换为其他类型

3
假设我有一个父类型的数组或向量。为了将其传递给函数,我需要它成为某个子类型(我预先知道所有元素都保证是该子类型)。有没有一种方便的方法来做到这一点?目前我只能想到制作一个全新的数组。
此外,看起来它不允许我反过来做:它不会接受子类型的数组代替父类型。有没有一个好的方法来解决这种情况?
看起来 `cast v` 可以工作,但这是首选的方式吗?
1个回答

6
为了将其传递给函数,我需要它成为某个子类型(我事先知道所有元素都保证是该子类型)。
如果你确信这是情况,可以使用强制转换是安全的。我认为没有更漂亮的方法来做到这一点,也不应该有,因为它本质上并不美观。经常需要这样做表示您的代码或正在使用的API存在设计缺陷。
对于反向情况,了解为什么不安全是有帮助的。原因并不一定那么直观,因为思考过程如下:
“我可以将Child分配给Base,那么为什么不能将Array分配给Array?”
这个确切的例子用来解释Variance。你应该完整地阅读Haxe手册,但我在这里会给出一个快速概述:
var children = [new Child()];
var bases:Array<Base> = cast children;
bases.push(new OtherChild());

children[1].childMethod(); // runtime crash

如果您可以将Array<Child>分配给Array<Base>那么您就可以将与Child不兼容的类型push()到其中。但正如您所提到的,您可以像上面的代码片段中一样cast它来使编译器静音。

然而,这并不总是安全的——可能仍然有代码持有对原始Array<Child>的引用,现在突然包含了它不期望的内容!这意味着我们可能会在一个没有该方法的对象上调用childMethod(),从而导致运行时崩溃。

相反,如果没有代码保留这样的引用(或者如果引用是只读的,例如通过haxe.ds.ReadOnlyArray),那么使用cast是安全的。


说到底,这是在性能成本和对编译器的信任之间做权衡(根据大小可能可以忽略不计)。你需要考虑清楚自己是否比编译器更聪明、是否知道所有存在的引用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接