假设我有一些父类型的数组或向量。要将它传递给函数,我需要它是一些子类型(我事先知道所有元素都保证是所有子类型)。有没有方便的方法呢?现在我只能想一个全新的阵列。
此外,它看起来不会让我这样做:它不会接受父类型的子类型数组。还有一种解决这种情况的好方法吗?
它看起来像cast v
工作,但这是首选方式?
要将它传递给函数,我需要它是一些子类型(我事先知道所有元素都保证是所有子类型)。
如果你真的相信这种情况,使用cast
是安全的。我不认为有任何更漂亮的方式这样做,也不应该有,因为它本身并不漂亮。必须这样做通常表明您的代码或正在使用的API存在设计缺陷。
对于相反的情况,理解为什么它不安全是有帮助的。由于这个思考过程,原因不一定是直观的:
我可以将
Child
分配给Base
,为什么我不能将Array<Child>
分配给Array<Base>
?
这个确切的例子用于解释方差in the Haxe Manual。你一定要完整阅读,但我会在这里给出一个快速摘要:
var children = [new Child()];
var bases:Array<Base> = cast children;
bases.push(new OtherChild());
children[1].childMethod(); // runtime crash
如果你可以将Array<Child>
分配给Array<Base>
,那么你可以将push()
类型与Child
不兼容。但同样,正如你所提到的,你可以像上面的代码片段那样使cast
静音编译器。
然而,这并不总是安全的 - 可能仍然有代码持有对原始Array<Child>
的引用,现在突然包含它不期望的东西!这意味着我们可以做一些事情,比如在没有该方法的对象上调用childMethod()
,并导致运行时崩溃。
反之亦然,如果没有代码保留这样的引用(或者引用是只读的,例如通过haxe.ds.ReadOnlyArray
),使用cast
是安全的。
在一天结束时,在制作副本的性能成本(根据大小可能可以忽略不计)和您对编译器/知道存在的所有引用更聪明的信心之间进行权衡。