class Test
{
public var field1:SomeClass;
public var field2:SomeClass = new SomeClass();
}
class Main
{
var test:Test = new Test();
public static function start(){
if(Test.field1 is SomeClass)
{
trace("yay!");
}
else if(Test.field1 is null)
{
trace("boo");
}
else
{
trace("None of those");
}
if(Test.field2 is SomeClass)
{
trace("yay!");
}
else if(Test.field2 is null)
{
trace("boo");
}
else
{
trace("None of those");
}
}
}
大家好,在上面的例子中是Main.start();会回来嘘!分别表示在初始化之前无法知道字段的类型是什么。问题是: 1)有没有解决这个问题的方法? 2)也许可以做一些像新的Test.field1这样的东西,然后用预期的类初始化它而不指定实际的类?
答案 0 :(得分:1)
public var field1; // this is a loosely typed variable.
public var field2:*; // this is an untyped variable.
如果要将类型检查推迟到运行时,可以使用* special type“。可以使用非类型化属性或表达式来规避严格模式下的编译时类型检查。但是,请注意,运行时类型无论你是否使用严格模式,都会检查赋值语句。“
这与在对象或数组中隐式声明数据类型相同。
var foo:Array = ["Apple", 123, true];
如果要跟踪每个类型,您会看到:
0:"Apple" (String)
1:123 (Number)
2:true (Boolean)
每个数组值在添加到数组时都在运行时隐式定义,而不是预定义的数据类型。
is
运算符的问题在于比较会运行继承链。如果你有一桶Sprite,MovieClips,Objects和Arrays,你可能会想象一个像这样的过滤器:
function sortBucket(foo:*):void {
if (foo is Object) {
// put it in the object bucket
} else if (foo is Array) {
// put it in the array bucket
} else if (foo is Sprite) {
// put it in the sprite bucket
} else if (foo is MovieClip) {
// put it in the MovieClip bucket
}
}
你会发现所有foo
都会进入第一个条件,被过滤到你的“对象桶”中。这是因为所有Arrays
,Sprites
和MovieClips
都从Object
继承,因此等于一。
参见继承图表......
更精确的解决方案可能是使用getQualifiedClassName()
。以下是我的解决方案:
function getType(value:*):String {
// Returns the type of object passed to it, as a string.
var msg:String = flash.utils.getQualifiedClassName(value);
if (msg.lastIndexOf("::") != -1) {msg = msg.split("::")[1];}
return msg;
}
现在,当提供无类型变量时,getType()
将返回存储的隐式数据类型。这是经过修改的铲斗分拣机(实际上有效)......
function sortBucket(foo:*):void {
switch (getType(foo)) {
case "Object":
// put it in the object bucket
break;
case "Array":
// put it in the array bucket
break;
case "Sprite":
// put it in the sprite bucket
break;
case "MovieClip":
// put it in the MovieClip bucket
break;
}
}