2011-07-24 11 views
5

निम्नलिखित स्काला घोषणाओं ठीक कर रहे हैं:स्कैला जेनरिक: इंटरेबल के अनुरूप नहीं है?

trait Base[B <: Base[B,M,ID], M <: Meta[B,M,ID], ID <: Comparable[ID]] { 
    // ... 
} 

trait Meta[B <: Base[B,M,ID], M <: Meta[B,M,ID], ID <: Comparable[ID]] extends Ordered[Meta[_,_,_]] { 
    // ... 
} 

trait BaseWithID[B <: BaseWithID[B,M,ID], M <: Meta[B,M,ID], ID <: Comparable[ID]] extends Base[B,M,ID] with Ordered[B] { 
    // ... 
} 


trait BaseWithIntID[B <: BaseWithIntID[B,M,ID], M <: MetaWithIntID[B,M,ID], ID <: Comparable[ID]] extends BaseWithID[B,M,ID] { 
    // ... 
} 

trait MetaWithIntID[B <: BaseWithIntID[B,M,ID], M <: MetaWithIntID[B,M,ID], ID <: Comparable[ID]] extends Meta[B,M,ID] { 
    // ... 
} 

लेकिन निम्न दो नहीं हैं:

trait BaseWithIntID[B <: BaseWithIntID[B,M], M <: MetaWithIntID[B,M]] extends BaseWithID[B,M,Int] { 
    // ... 
} 

trait MetaWithIntID[B <: BaseWithIntID[B,M], M <: MetaWithIntID[B,M]] extends Meta[B,M,Int] { 
    // ... 
} 

अंतर यह है कि मैं BaseWithIntID और MetaWithIntID में आईडी प्रकार पैरामीटर हटा दिया, और इंट निर्दिष्ट स्पष्ट रूप में है उनके संबंधित आधार लक्षण। लेकिन यह संकलित नहीं करता है, तो क्या इसका मतलब यह है कि Intala Scala में तुलनात्मक नहीं है? यदि यह है, तो मैं क्या गलत कर रहा हूँ? मैंने तुलनात्मक के बजाय ऑर्डर किया, और इससे कोई फर्क नहीं पड़ता।

मैं ग्रहण का उपयोग कर रहा है, और हमेशा की तरह, त्रुटि संदेश बेकार कर रहे हैं:

type arguments [B,M,Int] do not conform to trait BaseWithID's type parameter bounds [B <: BaseWithID[B,M,ID],M <: Meta[B,M,ID],ID <: java.lang.Comparable[ID]] 

यह सिर्फ का कहना है कि कुछ गलत हो रहा है, लेकिन नहीं है जो प्रकार पैरामीटर गलत है, और क्यों। this question पर देखकर, मैंने सोचा कि मैं इसके बजाय "आईडी <% तुलनात्मक [आईडी]" कोशिश कर सकता हूं, लेकिन यह एक विशेषता घोषणा में कानूनी नहीं है।

वास्तव में, यह या तो काम नहीं करता है (एक ही त्रुटि संदेश के साथ):

trait TestBase extends BaseWithID[TestBase,TestMeta,Int] 

trait TestMeta extends Meta[TestBase,TestMeta,Int] 
+0

'आईडी <% तुलनात्मक [आईडी] 'के साथ समस्या यह है कि यह स्वचालित रूप से एक अंतर्निहित पैरामीटर को परिभाषित करता है। चूंकि लक्षणों को पैरामीटर रखने की अनुमति नहीं है, इसलिए यह काम नहीं करेगा। एक 'वर्ग' के रूप में, हालांकि, आप इसे कर सकते हैं। –

उत्तर

8

इंट वास्तव में स्कैला में तुलनीय नहीं है, निश्चित रूप से यह वास्तव में जावा int के रूप में लागू किया गया है, java.lang.Integer नहीं। मुझे यकीन नहीं है कि असंभव होता, सी # struct (मूल्य प्रकार) इंटरफेस को कार्यान्वित कर सकता है, लेकिन यह यहां नहीं किया गया है।

आप आमतौर पर क्या कहते हैं कि के साथ आपके आईडी प्रकार के लिए निहित दायरे में उपलब्ध Ordering है।

एक सरल उदाहरण पर:

import Ordering.Implicits._ 
def max[A : Ordering](x: A, y: A) : A = if (x > y) then x else y 

यह एक आदेश कार्य करने के लिए (जो एक java.util.Comparator के समान है) गुजर रहा होता है। दरअसल, घोषणा

def max[A : Ordering](x: A, y: A) 

def max[A](x: A, y: A)(implicit ev: Ordering[A]) 

जहां ev एक ताजा नाम है करने के लिए अनुवाद। यदि ए: विधि परिभाषा के बजाए कक्षा पर ऑर्डरिंग दिखाई देती है, जैसे कि आपके कोड में, यह कन्स्ट्रक्टर को एक अंतर्निहित पैरामीटर में अनुवाद करता है, जो आवश्यक होने पर फ़ील्ड में रखा जाएगा, और कक्षा में निहित क्षेत्र में उपलब्ध होगा।यह Comparable (Ordered स्कैला में) को मजबूर करने से अधिक लचीला है क्योंकि इसका उपयोग उस वर्ग पर किया जा सकता है जो आपके नहीं है और तुलनात्मक लागू नहीं किया गया है। आप एक ही कक्षा में अलग-अलग ओडरिंग के बीच भी चयन कर सकते हैं, अगर केवल डिफ़ॉल्ट को उलटकर: def reverse : Ordering विधि Ordering पर है जो बस यही करती है।

खराब तरफ, यह संभावना नहीं है कि वीएम तुलनात्मक तरीके से कॉल को रेखांकित करने में सक्षम होगा, लेकिन यह सामान्य रूप से एक सामान्य रूप से एक इंटरफेस विधि के साथ नहीं था।

प्रकार जो जावा में Comparable<T> लागू स्वचालित रूप से वस्तु Ordering में एक अंतर्निहित विधि (ordered) के आधार पर अंतर्निहित दायरे में एक Ordering मिलता है। एक जावा Comparator<T> को Ordering (Ordering.comparatorToOrdering) में भी परिवर्तित किया जा सकता है।

ऑर्डरिंग आयात करना IIplicits._ आपको x > y सिंटैक्स की अनुमति देता है, जब Ordering[A] निहित क्षेत्र में होता है।

0

का जवाब "है कि मतलब यह है कि इंट स्काला में तुलनीय नहीं है?" जाहिर है हाँ, क्योंकि अगर मैं int.vang.Integer के साथ Int को प्रतिस्थापित करता हूं, तो यह त्रुटि के बिना संकलित करता है। समस्या यह है कि, जब भी मैं आईडी तक पहुंचता हूं, तो मैं एक रैपर ऑब्जेक्ट बनाने के लिए समाप्त होता हूं, जो अक्सर होता है और इसलिए महंगा होता है।

मैं यह निर्दिष्ट करना चाहता था कि आईडी तुलनात्मक/आदेशित है ताकि मैं बेसविथिड को स्वयं आदेश दे सकूं, और तुलनीय आईडी का उपयोग कर तुलनात्मक रूप से तुलना विधि को परिभाषित कर सकूं।

इस समय समाधान यह निर्दिष्ट नहीं करता है कि आईडी का आदेश दिया गया है, और ठोस वर्ग लागू करने की बजाय इसे एक ही समय में लागू करने के बजाय, तुलना करें। क्या किसी को बेहतर समाधान मिला है?

+0

मेरे जवाब में जोड़ने के लिए, "महंगे" पहलू पर, तुलना विधि - ऑर्डरिंग डॉट कॉम (एक्स, वाई) पर कॉल - शायद इनलाइन नहीं किया जाएगा, और आप मुक्केबाजी भी दे सकते हैं। तो यह तुलनात्मक रूप से जावा में होगा। दूसरी तरफ, एक्स> वाई को बुलाया जा सकता है, इसका अर्थ है नया ord.Ops (x)।> (Y), जो कार्यान्वयन बिंदु से नए ऑर्डरिंग.ऑप्स (ord, x), जहां ord है आदेश यह काफी संभव है कि इस वस्तु का निर्माण टाला जा सके। यदि आवश्यक हो (बेंचमार्क) आप ऑर्डरिंग.com सीधे कॉल कर सकते हैं, जो जावा में तुलना करने से ज्यादा बुरा नहीं होगा। –

+0

पीएस "संभव है कि इस वस्तु के निर्माण से बचा जा सके" मतलब "संभव है कि वीएम वास्तव में वस्तु नहीं बनायेगा"। यह केवल संभव नहीं है, लेकिन निश्चित है कि आप x> y वाक्यविन्यास का उपयोग न करके ऑब्जेक्ट के निर्माण से बच सकते हैं। –

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