问题描述
我正在尝试将一种类型的数组视为另一种(抽象)类型的数组。当我使用抽象的基础类型时,它可以正常工作。但是,当我尝试使用另一种类型(使用 @:from
关键字定义)进行隐式转换时,出现构建失败。
I'm attempting to treat an array of one type as an array of another (abstract) type. It works fine when I use the underlying type of the abstract. But when I attempt implicit conversion using another type (defined using @:from
keyword), I get a build failure.
如果我使用显式的 cast
,它可以工作,但是我想知道-有什么办法解决/
It works if I use an explicit cast
, but I'm wondering - is there any way around this / something I'm missing?
在以下示例中,出现构建失败 Array< Int>应该是Array< StringAbstract>
In the example below, I get the build failure Array<Int> should be Array<StringAbstract>
class Test {
static function main() {
var test:String = "Hello World";
print(test); //this works
var testArr:Array<String> = ["Hello", "World"];
printArray(testArr); //this works (using underlying type)
var testInt:Int = 10;
print(testInt); //this works
var testIntArr:Array<Int> = [1, 2, 3];
printArray(cast testIntArr); //this works (explicit cast)
printArray(testIntArr); //build failure (using @:from)
}
static function print(s:StringAbstract) {
trace(s);
}
static function printArray(arr:Array<StringAbstract>) {
trace(arr);
}
}
abstract StringAbstract(String) from String to String {
inline function new(s:String) {
this = s;
}
@:from
static public function fromInt(i:Int) {
return new StringAbstract(Std.string(i));
}
}
跟进
根据Gama11和Justinfront的建议,我定义了一个摘要,将数组转换为我的抽象类型的数组。但是,现在我遇到了另一个问题-声明@:from函数后,它就会破坏以前可以正常工作的代码。
Taking suggestions from Gama11 and Justinfront, I defined an abstract to convert arrays to arrays of my abstract type. But now I'm running into a different issue - as soon as I declare a @:from function, it breaks code that used to work.
具体地说,我以前能够使用隐式转换为抽象的混合类型调用我的函数(例如 printArray([1, 2,3]);
)。
Specifically, I used to be able to call my function with "mixed" types that were implicitly converted to the abstract (e.g. printArray([1, "2", 3]);
).
但是,一旦我添加了 @:from
函数即可从其他类型的数组( Array< Int>
),该功能中断了,并出现错误仅当类型强制为Array< Dynamic>时,才允许使用混合类型的数组。
。
But as soon as I added a @:from
function to convert from a different type of array (Array<Int>
in this case), that functionality broke, with the error Arrays of mixed types are only allowed if the type is forced to Array<Dynamic>
.
好奇是否有人知道原因(例如:)。
Curious if anyone knows why this would be (example: https://try.haxe.org/#65D03).
class Test {
static function main() {
var testMixedArr:Array<StringAbstract> = [1, "2", 3];
printArray(testMixedArr); //this works
printArray([1, "2", 3]); //this doesn't work, unless I remove "fromIntArray" function
}
static function printArray(arr:StringAbstractArray) {trace(arr);}
}
abstract StringAbstractArray(Array<StringAbstract>) from Array<StringAbstract> to Array<StringAbstract> {
inline function new(s:Array<StringAbstract>) {
this = s;
}
@:from
static public function fromIntArray(intArr:Array<Int>) {
return new StringAbstractArray(Lambda.array( Lambda.map( intArr, function(i: Int):StringAbstract {
return i; } )));
}
}
推荐答案
解决此问题的唯一方法是定义一个显式的 @:from
函数,该函数采用 Array< Int>
。 《 Haxe手册》 中对此进行了解释。它有一个很好的例子,说明这种情况下的强制转换如何导致运行时执行不安全的代码(而不是被编译器捕获)。
The only way around this is to define an explicit @:from
function that takes an Array<Int>
. The reason for this is explained in the Variance section of the Haxe Manual. It has a good example of how casting in this case can lead to unsafe code being executed at runtime (rather than being caught by the compiler).
这篇关于Haxe摘要-使用@:from时可以隐式转换数组吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!