2009-06-15 14 views
18

मैं क्या 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

ध्यान दें कि सामान्य रूप में लेट बाइंडिंग, जो अक्सर उपयोगी है, एफएफएफ की अपनी व्याख्या के साथ सीधे संघर्ष में है। – dkretz

+0

यह सच है, यह एक्शनस्क्रिप्ट में भी अपरिहार्य है क्योंकि "जेनेरिक" की कोई धारणा नहीं है, इसलिए कंटेनरों से बाहर निकलने वाली चीज़ें अनियमित होंगी। –

+0

(इसलिए यह 'var foo: foo = foo (myArray [i]) पर विफल होने के बजाय बेहतर है और कहीं और एनपीएक्स से निपटने के बजाय) –

उत्तर

12

आपको दो परिदृश्यों में डालने के लिए as का उपयोग करने की आवश्यकता है: Date पर कास्टिंग, और Array पर कास्टिंग करें।

तिथियों के लिए, Date(xxx) पर कॉल Date().toString() जैसा ही व्यवहार करता है।

सरणी के लिए, Array(xxx) पर एक कॉल एक तत्व के साथ Array बनाएगा: xxx।

Class() कास्टिंग विधि से अधिक तेजी से 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); 

पहले तत्व में मूल सरणी के साथ लंबाई की एक सरणी उत्पन्न करेगा। यदि आप निम्नानुसार 'as' का उपयोग करते हैं, तो आपको निष्कासित परिणाम मिलते हैं।

var goodArray:Array; 
goodArray = obj as Array; 

आम तौर पर, 'के रूप में' ActionScript में ') कक्षा (' ​​के लिए बेहतर है, क्योंकि यह अधिक अन्य भाषाओं में कास्टिंग की तरह व्यवहार करता है।

+1

जब आप "अन्य भाषाएं" कहें, तो आप किस बारे में सोच रहे हैं ? मुझे यकीन है कि यदि आप खराब कास्ट करने का प्रयास करते हैं तो जावा अपवाद उठाएगा ... –

+0

यदि आप सूची सूची = (सूची ) ओबीजे करते हैं तो जावा एक सूची को ठीक से परिवर्तित करेगा; कोई अपवाद नहीं, कोई समस्या नहीं है। आप एएस, समस्या में ऐरे (ओबीजे) करते हैं। – stevedbrown

26

इस चर्चा ध्यान देने योग्य में अंक की एक जोड़ी रहे हैं।

दो कामों में कक्षा में एक बड़ा अंतर है, कक्षा() ऑब्जेक्ट को निर्दिष्ट कक्षा में डालने का प्रयास करेगी, लेकिन ऐसा करने में विफलता पर (कभी-कभी, डेटाटाइप पर निर्भर करता है) रनटाइम त्रुटि फेंक देता है। दूसरी ओर कक्षा के रूप में ऑब्जेक्ट का उपयोग करने से पहले एक प्रकार की जांच पूर्ववत हो जाएगी, और यदि निर्दिष्ट ऑब्जेक्ट को इंगित क्लास में नहीं डाला जा सकता है तो इसके बजाय शून्य मान वापस कर दिया जाता है।

यह एक बहुत ही महत्वपूर्ण अंतर है, और विकास में एक उपयोगी उपकरण है। यह हमें निम्नलिखित करने की अनुमति देता है:

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

if(o) 
{ 
    //do stuff 
} 

मुझे लगता है कि इसकी उपयोगीता स्पष्ट है।

"as" शेष भाषा के साथ भी अधिक संगत है (यानी: "myObject 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 

यह एक अच्छा और महत्वपूर्ण विषय है, एक प्रकार है:

MyClass() विधि जब सरल डेटा प्रकार (पूर्णांक, संख्या, uint, स्ट्रिंग) इस के कुछ उदाहरण हैं के साथ काम कर अतिरिक्त लाभ है सामान्य नियम मैं सरल डेटा प्रकारों का उपयोग करते समय ऑब्जेक्ट्स और कास्ट() के साथ काम करते समय "as" का उपयोग करता हूं, लेकिन यह है कि मैं अपने कोड को कैसे व्यवस्थित करना चाहता हूं।

+0

'as' भाषा के साथ अधिक संगत हो सकता है, लेकिन क्या यह अभी भी अधिक खतरनाक नहीं है? हालांकि प्रतिक्रिया के लिए धन्यवाद - int/string/number कास्टिंग की जटिलताओं को जानना अच्छा होता है। –

+0

आप इसके बारे में और अधिक खतरनाक क्या महसूस करते हैं? खतरनाक क्या है सभी परिस्थितियों को ठीक तरह से संभालना नहीं है, लेकिन यह डेवलपर मुद्दा एक भाषा नहीं है। मुझे वास्तव में यह सुरक्षित है (प्रकार की जांच), और अविश्वसनीय रूप से उपयोगी, और परिणामस्वरूप क्लीनर कोड हो सकता है। var o: कक्षा = एक [i] कक्षा के रूप में || नई कक्षा(); // इस तरह की चीज़ के लिए महान –

+0

यह स्पष्ट करने के लिए कि मुझे क्यों लगता है कि यह सुरक्षित है: यह आपको विफल होने पर चीजों को तोड़ने के बिना एक प्रकार का कलाकार बनाने की अनुमति देता है। –

0

जब मैं ऑब्जेक्ट्स का ऐरे कोलेक्शन करता हूं तो इसका उपयोग करता हूं और उन्हें चयन करने की आवश्यकता होती है, या चयनकर्ता फ़ंक्शन का उपयोग करें।

उदा।

वर एबीसी: MyType = mycollection.getItemAt (i) MyType रूप

+0

लेकिन आप 'var' 'var abc पर क्यों उपयोग करते हैं: MyType = MyType (mycollection.getItemAt (i))'? 'as' का उपयोग करके एक सूक्ष्म बग की संभावना का परिचय देता है यदि' mycollection' में कुछ ऐसा है जो 'माईटाइप' नहीं है (असफलता नियम देखें) –

+0

मैं इसका उपयोग करता हूं क्योंकि मेरे लिए MyType (...) मानसिक रूप से एक है कास्ट और "माईटाइप" मानसिक रूप से एक उपनाम है, और मैं इसे कास्ट नहीं कर रहा हूं बल्कि यह कह रहा हूं कि संकलक को खुश करना है (भले ही वे इस मामले में समान हों)। लेकिन मैं घंटी के आकार के वक्र के बतख-टाइपिंग अंत में हूं, इसलिए संभवतः यह कोड के बारे में सोचने के तरीके पर एक प्रतिबिंब है - मैं इसे सभी कोनों पर बटन-अप करने के बजाय स्पष्ट और सरल रखना चाहता हूं। मुझे खुशी है कि उन्होंने जावास्क्रिप्ट को इसके अलावा क्रियालेख बनाने के बजाय अकेले पर्याप्त छोड़ दिया है। मैं "if (! Object) {}" का निर्माण भी किसी अन्य उत्तर में उल्लिखित निर्माण का उपयोग करता हूं। – dkretz

5

वे वास्तव में अलग अलग बातें ... करते हैं जब आप कहते हैं

myvar as ClassName 

आप वास्तव में सिर्फ संकलक दे रहे हैं पता है कि इस उद्देश्य यह है कि या तो एक className या 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

ठीक है, मैं देखता हूं। तो क्या यह संभव है कि, अपने स्वयं के प्रकार के जबरन नियमों को परिभाषित किया जाए? उदाहरण के लिए, अगर मैं कलर क्लास लिखना चाहता था, तो मैं कंपाइलर को कैसे बता सकता हूं कि 'रंग (0x443322) '0x44 लाल, 0x33 हरा और 0x22 नीला रंग वाला रंग है? –

+0

@ डेविड सुनिश्चित नहीं है कि आपकी रंगीन कक्षा कैसे स्थापित की जाती है लेकिन वे आमतौर पर यूंट के रूप में सेट की जाती हैं। आम तौर पर एक रंग की उम्मीद है कि वास्तव में एक संकेत की उम्मीद है। सामने 0x का मतलब है कि 0x443322 एक हेक्साडेसिमल संख्या है, जो 4469438 यूआईंट का अनुवाद करता है। तो आपको इसे बदलने की जरूरत नहीं है, लेकिन यदि आप करते हैं, तो मुझे लगता है कि रंग .tocolor (0x443322) जैसी स्थिर विधि बनाने का सबसे अच्छा तरीका होगा; –

संबंधित मुद्दे

 संबंधित मुद्दे