2012-03-25 4 views
10

आम तौर पर अगर आप एक Stream वस्तु बनाने, सिर बेसब्री से मूल्यांकन किया जाएगा:स्ट्रीम के प्रमुख का मूल्यांकन कब किया जाता है?

scala> Stream({println("evaluating 1"); 1} , 2, 3) 
evaluating 1 
res63: scala.collection.immutable.Stream[Int] = Stream(1, ?) 

हम एक धारा जो हम एक ही बयान में पहले जोड़ें करने के लिए बनाते हैं, तो यह थोड़ा आश्चर्य की बात लगता है कि सिर से पहले मूल्यांकन नहीं किया गया है समामेलन अर्थात

scala> 0 #:: Stream({println("evaluating 1"); 1} , 2, 3) 
res65: scala.collection.immutable.Stream[Int] = Stream(0, ?) 

(#:: राइट साहचर्य और ConsWrapper पर आगे जोड़ते विधि है, जो Stream का एक अंतर्निहित वर्ग है। है)

कैसे इस 0 prepending से पहले उसके सिर का मूल्यांकन नहीं करता है? क्या यह है कि पूंछ स्ट्रीम (या विपक्ष सेल) ढेर पर मौजूद नहीं है जब तक हम परिणामी स्ट्रीम से मूल्य नहीं ले लेते? लेकिन यदि हां, तो हम उस ऑब्जेक्ट पर #:: विधि को कैसे कॉल करते हैं जो अभी तक मौजूद नहीं है?

+1

मेरा सुझाव है कि आप यह समझने के लिए 'जावप' का उपयोग करें कि क्या हो रहा है। –

+0

मैंने यह पाया कि स्रोत को देखकर (मेरा जवाब सही है) –

उत्तर

7

-Xprint:typer आपका मित्र है, कभी भी आप यह समझना चाहते हैं कि कुछ कोड का मूल्यांकन कैसे किया जाता है या प्रकार अनुमानित होते हैं।

scala -Xprint:typer -e '0 #:: Stream({println("evaluating 1"); 1} , 2, 3)' 

val x$1: Int = 0; 
Stream.consWrapper[Int](Stream.apply[Int]({ 
    println("evaluating 1"); 
    1 
}, 2, 3)).#::(x$1) 

consWrapper का पैरामीटर उप-नाम है। तो यह भी काम करता है:

scala> (1 #:: (sys.error("!!"): Stream[Int])).head 
res1: Int = 1 
+0

+1 '-e' का उपयोग करने के लिए। मुझे लगता है कि पर्ल के कहने के मुकाबले यह बहुत कम इस्तेमाल होता है। –

+0

मुझे अब मिल गया है। यह भी महत्वपूर्ण है कि धारा से ConsWrapper के निहित डीफ़ का नाम है। 'निहित डीफ consWrapper [ए] (धारा: => स्ट्रीम [ए])'। यह संभवतः क्यों है 'ConsWrapper' मौजूद है, और '# ::' सीधे' स्ट्रीम' पर एक विधि नहीं है: ताकि स्ट्रीम को इस विधि को कॉल करने के लिए नहीं बनाया जाना चाहिए - आपको बस 'ConsWrapper' ऑब्जेक्ट मिलता है जिसमें कार्यक्षमता का सबसेट शामिल है। –

5

धारा के निर्माण के समय सिर का मूल्यांकन किया जाता है।

लेकिन आपके दूसरे उदाहरण में आप #:: पर दूसरे तर्क के रूप में स्ट्रेम को पास नहीं करते हैं, तो आप नाम पैरामीटर पास करते हैं, यानी पूर्ण अभिव्यक्ति Stream({println("evaluating 1"); 1} , 2, 3) का मूल्यांकन नहीं किया जाता है।

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