2010-12-18 21 views
6

आप में उस दृश्य को जानते हैं अलविदा और सभी मछली के लिए धन्यवाद जहां आर्थर इतनी प्रसन्नता से खुश है कि वह एक वेटर को रोकता है और जानना चाहता है, "यह खाना इतना अच्छा क्यों है?" मैं उस स्थिति में हूं। ऐसा लगता है कि स्कैला ठीक वही कर रहा है जो मैं चाहता हूं, लेकिन मुझे समझ में नहीं आता कि यह कैसा चल रहा है। निम्नलिखित पर विचार करें:मैं एक नील सूची कैसे संशोधित कर सकता हूं?

scala> var v = Nil:List[String]; 
v: List[String] = List() 

scala> v.length 
res38: Int = 0 

scala> v ::= "Hello" 

scala> v.length 
res39: Int = 1 

scala> Nil.length 
res40: Int = 0 

जो वास्तव में आप उम्मीद करेंगे, लेकिन यह कैसे हो रहा है?

नील एक वस्तु है जो सूची [कुछ भी नहीं] का विस्तार करती है, जो सूची [स्ट्रिंग] का एक उप प्रकार है, इसलिए असाइनमेंट ठीक काम करता है, लेकिन यह अपरिवर्तनीय सूची है, है ना? इसलिए मुझे इसमें शामिल नहीं होना चाहिए। लेकिन मैं इसमें शामिल हो सकता हूं, या कम से कम मैं वी में शामिल हो सकता हूं, जिसे मैंने नील को इंगित किया था। वी बदल गया है, लेकिन नील नहीं है।

तो, डब्ल्यूटीएफ? क्या स्कैला में कुछ चालाक प्रति-संशोधित अर्थशास्त्र है, मुझे अनजान है? क्या नील वास्तव में एक समारोह है जो खाली सूचियां देता है? अधिक व्यापक रूप से, क्या कोई तरीका है कि मैं आरईपीएल इन सवालों के जवाब दे सकता था?

उत्तर

16

जब स्काला

v ::= "Hello" 

यह पहली चेकों को देखता है, तो v विधि ::= को जानता है।

v = v.::("Hello") 

जो संयोगवश, "Hello" :: v लिखा है: इस मामले (प्रकार List) क्योंकि विधि केवल प्रतीक शामिल हों और एक = संकेत साथ समाप्त होता है, यदि ऐसा नहीं होता है, तो, में, यह कुछ और कोशिश करता है इंफिक्स नोटेशन में। अब, v विधि :: जानता है, जो काम करता है और एक नया List देता है, जिसे तब संकेत दिया गया है v

वैसे, यह तैयार है, संलग्न नहीं है।

4

जब आप कीवर्ड var आप नहीं जावा अर्थ में "final में अनुवाद" कर रहे हैं का उपयोग करें। इसके बजाय, var पुन: असाइनमेंट की अनुमति देता है। जब आप ऑपरेटर ::= पर कॉल करते हैं तो आप वास्तव में v अंक को पुन: असाइन कर रहे हैं। ऑपरेटर ::=नई सूची देता है, न कि इसमें "हैलो" के साथ मूल सूची नहीं है। इसलिए, v अब "हैलो" पर इंगित कर रहा है और Nil सूची नहीं है।

यहाँ, इस घड़ी:

var myThing = new List(1, 2, 3) 
var myOhterThing = myThing 

myThing = new List(1, 2, 3, 4) 

यह कह रही है "पहली सूची लेने के रूप में लगभग एक ही है, यह कॉपी करें और पर एक '4' संलग्न अब जब कि सूची को इंगित करने के लिए 'myThing' निर्दिष्ट करते हैं।। " उस ऑपरेटर का उपयोग करके आपने वही काम किया है। इसे इस तरह से लिखने से आप इसे देख सकते हैं।

2

नील अपरिवर्तनीय है। जब आप इसे मानते हैं (: :) आपको एक नया उदाहरण मिलता है जो अपरिवर्तनीय भी है।

इस प्रयास करें:

val v1 = Nil 
val v2 = "Hello" :: v1 
v1 == v2 

(आप गलत हैं क्योंकि वे एक ही वस्तु को इंगित नहीं है मिल जाएगा)

को देखते हुए वी एक वर आप इसे करने के मूल्यों को पुन: असाइन कर सकते हैं।

तो आपके पास:

v ::= "Hello" // what you really have is: 
v = "Hello" :: v // or 
v = "Hello" :: Nil // or 
v = List("Hello") 

ऊपर एक नई सूची बनाता है और शून्य में कोई बदलाव नहीं छोड़ दिया है। यह जावा में स्ट्रिंग अतिरिक्त के समान है। चूंकि स्ट्रिंग अपरिवर्तनीय है, इसलिए आप कभी भी एक उदाहरण नहीं बदलते - केवल नए बनाते हैं।

के बाद से कोई नहीं नहीं बदला है, Nil.length = 0.

3

यह वैल वी के साथ प्रयास करें, क्या परिवर्तनशील है देखने के लिए। :)

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