如何将 Haxe Array/Vector 转换为另一种类型
How to convert Haxe Array/Vector to another type
假设我有一个父类型的数组或向量。要将它传递给一个函数,我需要它是某种子类型(我事先知道所有元素都保证是该子类型)。有方便的方法吗?现在我只能考虑制作一个全新的数组。
此外,它似乎不会让我反过来做:它不会接受子类型数组代替父类型。这种情况也有好的解决方法吗?
看起来 cast v
可行,但这是首选方式吗?
To pass it to a function, I need it to be some child type (which I know beforehand that all elements are guaranteed to be all that child type).
如果您真的确信是这种情况,使用 cast
是安全的。我不认为有任何更漂亮的方法可以做到这一点,也不应该有,因为它本质上并不漂亮。必须这样做通常表明您的代码或正在使用的 API 存在设计缺陷。
对于相反的情况,有助于理解为什么它不安全。原因不一定是因为这个思维过程那么直观:
I can assign Child
to Base
, so why can't I assign Array<Child>
to 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
),使用 [=11= 是安全的].
归根结底,这是制作副本的性能成本(根据大小可能可以忽略不计)与您对自己比编译器更聪明/了解的自信程度之间的权衡所有存在的引用。
假设我有一个父类型的数组或向量。要将它传递给一个函数,我需要它是某种子类型(我事先知道所有元素都保证是该子类型)。有方便的方法吗?现在我只能考虑制作一个全新的数组。
此外,它似乎不会让我反过来做:它不会接受子类型数组代替父类型。这种情况也有好的解决方法吗?
看起来 cast v
可行,但这是首选方式吗?
To pass it to a function, I need it to be some child type (which I know beforehand that all elements are guaranteed to be all that child type).
如果您真的确信是这种情况,使用 cast
是安全的。我不认为有任何更漂亮的方法可以做到这一点,也不应该有,因为它本质上并不漂亮。必须这样做通常表明您的代码或正在使用的 API 存在设计缺陷。
对于相反的情况,有助于理解为什么它不安全。原因不一定是因为这个思维过程那么直观:
I can assign
Child
toBase
, so why can't I assignArray<Child>
toArray<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
),使用 [=11= 是安全的].
归根结底,这是制作副本的性能成本(根据大小可能可以忽略不计)与您对自己比编译器更聪明/了解的自信程度之间的权衡所有存在的引用。