2012-06-30 23 views
8

मुझे लगता है मैं स्काला 2.10 के नए "मूल्य वर्ग" सुविधा को समझते हैं, हास्केल के newtype के साथ तुलना द्वारा:उपयोगकर्ता द्वारा परिभाषित मूल्य वर्ग जावा से क्या दिखते हैं?

trait BoundedValue[+This] extends Any { this: This => 

    def upperBound: This 

    def lowerBound: This 

} 

class Probability @throws(classOf[IllegalArgumentException]) (v: Double) extends AnyVal with BoundedValue[Probability] { 

    val value: Double = if ((v >= 0.0) && (v <= 1.0)) v else throw new IllegalArgumentException((v.toString) + "is not within the range [0.0, 1.0]") 

    override val upperBound: Probability = new Probability(0.0) 

    override val lowerBound: Probability = new Probability(1.0) 

    // Implement probability arithmetic here; 
    // will be represented by Double at runtime. 

} 

सवाल मैं, कैसे एक मूल्य वर्ग जावा कोड के लिए प्रकट होता है है स्काला पैकेज का उपयोग करता है जिसमें इसे घोषित किया गया है? क्या वैल्यू क्लास जावा तरफ से रेफरेंस क्लास के रूप में दिखाई देता है, या क्या यह पूरी तरह से मिटा दिया गया है (और इस प्रकार यह टाइप के रूप में दिखाई देता है)? दूसरे शब्दों में, जब जावा स्रोत स्रोत पर शामिल होता है तो प्रकार-सुरक्षित मूल्य वर्ग कैसे होते हैं?


संपादित

ऊपर कोड संकलन नहीं होगा, एसआईपी -15 दस्तावेज़ (डैनियल के जवाब में जुड़े हुए) के अनुसार, क्योंकि मूल्य कक्षाएं किसी भी आरंभीकरण तर्क है की अनुमति नहीं है, क्योंकि या तो v स्पष्ट रूप से एक वैल या Probability होना चाहिए unbox विधि और इसके साथी ऑब्जेक्ट पर box विधि होना चाहिए, और क्योंकि मूल्य वर्गों में बिल्कुल एक फ़ील्ड होना चाहिए। सही कोड है:

trait BoundedValue[This <: BoundedValue[This]] extends Any { this: This => 

    def upperBound: This 

    def lowerBound: This 

} 

class Probability private[Probability] (value: Double) extends AnyVal with BoundedValue[Probability] { 

    @inline override def upperBound: Probability = new Probability(0.0) 

    @inline override def lowerBound: Probability = new Probability(1.0) 

    @inline def unbox: Double = value 

    // Implement probability arithmetic here; 
    // will be represented by Double at runtime (mostly). 

} 

object Probability { 

    @throws(classOf[IllegalArgumentException]) 
    def box(v: Double): Probability = if ((v >= 0.0) && (v <= 1.0)) new Probability(v) else throw new IllegalArgumentException((v.toString) + "is not within the range [0.0, 1.0]") 

} 

प्रश्न स्वयं ही मान्य है, हालांकि।

+1

अपने परीक्षण कार्यक्रम में, क्या आप जावा से मान्य सीमाओं के बाहर लपेटा हुआ मूल्य धक्का दे सकते थे? –

+0

@ डेविड हार्नेसनेस मेरे पास 2.10.0-एम 4 के साथ एक मशीन तक पहुंच नहीं है, इसलिए मुझे नहीं पता। मैं जांच करूंगा कि मैं कब कर सकता हूं। –

उत्तर

6

मूल्य वर्ग सामान्य कक्षाओं के रूप में संकलित होते हैं, और संदर्भ के रूप में अच्छी तरह से प्रकट हो सकते हैं।

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

SIP-15 भी देखें, जो यांत्रिकी को बताता है।

+0

धन्यवाद! मैंने सोचा कि मैंने एसआईपी पढ़ी है, लेकिन मुझे लगता है कि मैंने नहीं किया था। –

+2

एक समान रूप से दिलचस्प सवाल है कि "प्लेटफ़ॉर्म पर स्केल मूल्य प्रकार कैसे एन्कोड किए गए हैं जिनके पास मूल्य प्रकार नहीं हैं (जैसे JVM)" है "स्काला मान प्रकार प्लेटफ़ॉर्म पर एन्कोड किए गए हैं जो * मान * के प्रकार हैं (उदाहरण के लिए CLI) "। उदाहरण के लिए, सीएलआई पर structs के लिए संकलित द्वारा स्केल मूल्य प्रकार कर सकते हैं? क्या यह गारंटी है कि वे * हमेशा * structs के लिए संकलित किया जाएगा? –

+1

आपका प्रश्न बहुत दिलचस्प है, लेकिन मुझे एहसास हुआ कि न केवल सीएलआई structs समर्थित हैं (एसआईपी में उनका उल्लेख नहीं किया गया था, पिछली बार मैंने इसे पढ़ा था), लेकिन वे शायद बेकार भी हैं। वैल्यू क्लास में केवल एक ही फ़ील्ड हो सकता है, जैसे हास्केल की नई विशेषताएं, इसलिए मुझे लगता है कि structs का उपयोग करना और प्राइमेटिव्स मदद नहीं करेंगे। स्ट्रक्चर के पास स्मृति उपयोग के लिए बहुत सारे फायदे हैं- लेकिन उनका उपयोग करने के लिए, एक अलग तंत्र प्रदान करना चाहिए, जो कि इस व्यवहार का अनुरोध करने वाला एक टिप्पणी है जिसे अनदेखा किया जा सकता है। अर्थपूर्ण समस्या यह है कि structs को केवल जेवीएम पर नहीं, केवल सीएलआई पर AnyVal से प्राप्त होना चाहिए। – Blaisorblade