2011-04-30 19 views
5

में एक आलसी वैल लौटने मैं एक समारोह है कि इस तरह दिखता है:स्काला

package org.thimblr.io 
import java.io._ 
object Local { 
    def streamer(path: String) =() => new FileReader(path) 
} 

यह मूलतः का प्रबंधन करता है कि मैं क्या जो एक समारोह एक फ़ाइल से एक धारा खुलती वापस जाने के लिए है, जब यह कहा जाता है ऐसा करने के लिए, चाहते हैं । तो ग्राहक कोड कर सकते हैं:

val planStreamSource = Local.streamer("/home/someuser/.plan") 
//...passes the function on to somewhere else 
val planStream = planStreamSource() 
val firstByte = planStream.read 
//can now read from planStream 

लेकिन क्या मैं वास्तव में चाहते हैं, एक आलसी वैल कि एक फ़ाइल से धाराओं एक बार यह संदर्भित है वापस जाने के लिए इस तरह है:

val planStream = Local.streamer("/home/someuser/.plan") 
//...passes the val on to somewhere else, without opening the file for reading yet 
val firstByte=planStream.read 
//...such that planStream was only just opened to allow the read 

यह संभव है ऐसा कुछ करें, आलसी वैल वापस करें, ताकि क्लाइंट कोड इसे फ़ंक्शन के बजाय मूल्य के रूप में देख सके?

+1

आप केवल डीईएफ स्ट्रीमर (पथ: स्ट्रिंग) = नया फ़ाइल रीडर (पथ) 'और 'आलसी वैल प्लानस्ट्रीम = लोकल.स्ट्रीमर ("/home/someuser/.plan ") क्यों नहीं करते हैं? –

+0

क्योंकि मैं इस वैल को कोड में कहीं और आपूर्ति करना चाहता हूं, एक धारा के साथ एक दूसरे के साथ, लेकिन एक सॉकेट या किसी और चीज़ से। अगर मैं किसी अन्य फ़ंक्शन के लिए तर्क के रूप में प्लानस्ट्रीम पास करता हूं, तो मैं नहीं चाहता कि फ़ाइल उस बिंदु पर अभी तक खोला जाए। मैं इसे खोला जाना चाहता हूं जब क्लाइंट कोड स्ट्रीम का उपयोग शुरू करने के लिए वास्तव में तैयार है (आखिरकार कोशिश करें ब्लॉक के अंदर)। – traffichazard

+0

स्कैला का इलाज करने की कोशिश कर रहा है जैसे कि यह आलसी मूल्यांकन की गई भाषा अपने अनाज के खिलाफ बुरी तरह से चल रही है। आप स्थगित-मूल्यांकन मूल्य कंटेनर बनाने के लिए आलसी 'वैल और उप-पैरामीटर पैरामीटर का उपयोग कर सकते हैं, लेकिन प्रोग्रामिंग की सिस्टम-व्यापी शैली के रूप में मुझे अनुशंसित नहीं किया जा सकता है। –

उत्तर

15

आप "एक आलसी वैल लौटने" कर सकते हैं - ग्राहक कोड के रूप में आलसी घोषित करना चाहिए। आप एक आलसी वैल घोषित करने के लिए ग्राहक के लिए मजबूर नहीं करना चाहते हैं, तो आप एक आवरण के बजाय लौट सकता है:

class LazyWrapper[T](wrp: => T) { 
    lazy val wrapped: T = wrp 
} 

object LazyWrapper { 
    implicit def unboxLazy[T](wrapper: LazyWrapper[T]): T = wrapper.wrapped 
} 

और फिर:

def streamer(path: String) = new LazyWrapper(new FileReader(path)) 

आप कर सकते थे आगे आगे equals, hashCode, आदि यदि आपको उनकी आवश्यकता है तो LazyWrapper में लिपटे ऑब्जेक्ट पर।

+0

मुझे यह पसंद है। मैं स्कैला के लिए नया हूं और कोशिश कर रहा हूं, किसी और चीज की तुलना में प्रयोग के लिए अधिक, एक कार्यात्मक शैली का पालन करने के लिए, इसलिए मैं कक्षा रैपर के बिना करने की कोशिश कर रहा था। लेकिन आपका सुझाव शायद ऐसा करने का सबसे पतला तरीका है। – traffichazard