2009-06-15 10 views
18

、そこキャストの2種類があります。またActionScript: 'キャスト'としてキャストを使用する理由はありますか?私は、ActionScriptの理解何から

var bar0:Bar = someObj as Bar; // "as" casting 
var bar1:Bar = Bar(someObj); // "class name" casting (for want of a better name) 

は、と私はここで間違っている場合は、私を修正してください、asキャスティングながら、クラスまたはnullのインスタンスを返します。どちらか"クラス名"キャストは、クラスのインスタンスを返すか、キャストが不可能な場合に例外を発生させます - これ以外は同じです。

しかし、asのキャスティングは、フェイル・ファースト・フェイル・ファースト・アーリーの原則に大きな違反と思われる...そして、むしろasキャストを使用することが望ましい状況を想像している。クラス名キャストよりも(おそらく、instanceofがそこに投げ込まれている)。

私の質問は、as鋳造を使用することが望ましい状況は何ですか?

+0

注意、 fffeの解釈と直接衝突することがよくあります。 「ジェネリック医薬品」という概念が存在しないと本当の – dkretz

+0

が、それはまた、ActionScriptで避けられないですので、あなたは、コンテナから出るものは型なしとなります。 –

+0

(それは、 'VAR fooのに失敗することが望ましいです:[i])とはFoo =はFoo(myarrayの'のではなくヌルを取得し、どこか別の場所NPXに対処)あなたが考えている「他の言語」を、言うとき –

答えて

12

Dateにキャストし、Arrayにキャストする2つのシナリオでキャストするには、asを使用する必要があります。

日付の場合、Date(xxx)の呼び出しは、新しいDate().toString()と同じように動作します。

配列の場合、Array(xxx)を呼び出すと、Arrayが1つの要素xxxで作成されます。

キャスト方法がasキャスティングより高速であることが示されているため、効率が重要な場合(および日付と配列を使用しない場合)はasよりも好ましい場合があります。

import flash.utils.*; 

var d = Date(1); 

trace("'" + d, "'is type of: ",getQualifiedClassName(d)); 

var a:Array = Array(d); 

trace("'" + a, "' is type of: ", getQualifiedClassName(a)); 

    //OUTPUT 
     //'Mon Jun 15 12:12:14 GMT-0400 2009 'is type of: String 
     //'Mon Jun 15 12:12:14 GMT-0400 2009 ' is type of: Array 

    //COMPILER ERRORS/WARNINGS: 
     //Warning: 3575: Date(x) behaves the same as new Date().toString(). 
     //To cast a value to type Date use "x as Date" instead of Date(x). 
     //Warning: 1112: Array(x) behaves the same as new Array(x). 
     //To cast a value to type Array use the expression x as Array instead of Array(x). 

`

1

配列として 'as'を使用してください。

var badArray:Array; 
badArray = Array(obj); 

最初の要素に元の配列を含む長さ1の配列が生成されます。次のように 'as'を使用すると、除外された結果が得られます。

var goodArray:Array; 
goodArray = obj as Array; 

一般に、ActionScriptでは 'as'が他の言語のキャストのように動作するため、ActionScriptでは 'Class()'よりも優先されます。

+1

?私は=あなたが 一覧リストをすれば –

+0

Javaが正しくリストに変換されます...あなたが悪いキャストを実行しようとした場合、Javaが例外を発生することを確実に知る(一覧)は、obj; 例外はありません。問題ありません。あなたはASで問題のArray(obj)を実行します。 – stevedbrown

26

注目に値するこの議論にあるポイントがいくつかあります。

Class()はオブジェクトを指定されたClassにキャストしようとしますが、失敗すると(データ型に依存することもあります)、ランタイムエラーが発生します。一方、Classとしてオブジェクトを使用すると、最初に型チェックが実行され、指定されたオブジェクトが指定されたClassにキャストできない場合は、null値が代わりに返されます。

これは非常に重要な違いであり、開発に役立つツールです。それは、私たちは次のことを行うことができます:

var o:MyClass = myArray[i] as MyClass; 

if(o) 
{ 
    //do stuff 
} 

私はその有用性はかなり明白だと思います。

"as"も他の言語と一貫しています(つまり、 "myObject is MyClass")。

単純なデータ型(int型、数、UINT、文字列)を扱う場合のMyClass()メソッドは、こののいくつかの例は、追加の利点があります。

var s:String = "89567"; 
var s2:String = "89 cat"; 
var n:Number = 1.9897; 

var i:int = int(s); // i is = 89567, cast works 
var i2:int = int(s2); //Can't convert so i2 is set to 0 
var i3:int = int(n); // i = 1 
var n2:Number = Number(s2); // fails, n2 = NaN 

//when used in equations you'll get very different results 
var result:int = int(n) * 10; //result is 10 
var result:int = n * 10; //result is 19.89700 
var result:int = int(s2) * 10; //result is 0 

trace(s2 as Number); //outputs null 
trace(s2 as int); //outputs null 
trace(Number(s2)); //outputs NaN 

これは良いと重要なトピックである、として一般的なルール単純なデータ型を使用するときは、ObjectとCast()を使って作業するときに「as」を使用しますが、これはコードを構造化する方法です。

+0

「as」は言語に一貫しているかもしれませんが、まだそれはもっと危険ですか? 応答のためにありがとう - int/string/numberキャストのintricaciesは知っておきたいです。 –

+0

あなたはそれについてもっと危険だと感じますか?危険なのは、すべての状況を適切に処理しているわけではありませんが、それは言語の問題ではなく、開発者の問題です。私は実際にそれがより安全だと感じています(タイプチェック)、そして非常に便利で、より洗練されたコードになることがあります。 var o:クラス= a [i]をクラスとして||新しいクラス(); //私はそれがより安全だと思う理由を明確にする事 –

+0

のこの種のための偉大な:それはあなたがそれが失敗した場合のものを壊すことなく、型キャストを試みることができます。 –

0

私はオブジェクトのArrayCollectionのを持っているし、それらを列挙、またはセレクタ機能を使用する必要があるとき、私はそれを使用します。

のvar ABC:MYTYPE = mycollection.getItemAt(I)MYTYPE

+0

しかし、なぜあなたは 'のvar ABC'オーバーas'使用します: 'がMyType =がMyType(mycollection.getItemAt(i)を)? 'my'は' MyType'ではないものが含まれていると微妙なバグの可能性があります(fail-fastルール参照) –

+0

MyType(...)は精神的にキャストと "as MyType"は精神的にエイリアスであり、私はそれをキャストしているのではなく、むしろコンパイラを幸せにすることを主張している(たとえそれらが同じであっても)。しかし、私は鐘型カーブのダックタイピングの終わりにいるので、おそらくコードについての考え方を反映していると思います。私はむしろ、すべてのコーナーでそれを明確かつシンプルにしたいと思っています。私は彼らがjavascriptだけではなく、十分なだけではなく、それからアクションスクリプトを残して満足しています。私はまた、別の答えに述べられている "if(!オブジェクト){}"の構文をかなり使います。 – dkretz

5

として彼らは実際には異なることを行うに...あなたは

myvar as ClassName 

を言うときあなたは本当にただ、コンパイラは、このオブジェクトを知らせるしていますあなたが言うとき、クラス名やクラス名

のサブクラスのいずれかです:

ClassName(myvar) 

実際には、そのタイプのオブジェクトに変換しようとします。

ので、あなたのオブジェクトは、またはクラスの下降であり、あなたはそれはあなたが

などとして使用することになり変換する必要がない場合:後半、一般的に結合

var myvar:String = '<data/>'; 
var othervar:XML = XML(myvar); //right 

var myvar:String = '<data/>'; 
var othervar:XML = (myvar as XML); //wrong 

var myvar:XML = <data/>; 
var othervar:XML = myvar as XML; // right 
+0

さて、わかりました。それで、自分の型強制変換規則を定義することは可能ですか?たとえば、Colorクラスを記述する場合、「Color(0x443322)」は「0x44赤、0x33緑、0x22青の色」であることをコンパイラにどのように伝えることができますか? –

+0

@Davidでは、Colorクラスの設定方法は不明ですが、通常はuintとして設定されます。通常、色を期待しているものは本当にuintを期待しています。正面の0xは、0x443322が16進数であることを意味し、4469438単位に変換されます。ですから、変更する必要はありませんが、そうした場合は、Color.toColor(0x443322)のような静的メソッドを作成するのが最善の方法だと思います。 –