2014-05-03 3 views
5

मैंने प्रश्न का उत्तर देखा: Can all usages of forSome be replaced by an equivalent usage of _?, लेकिन यह समझ में नहीं आया कि वास्तविक मामला क्या है जहां "कुछ" के बजाय "_" का उपयोग नहीं किया जा सकता है। मैं Programming in Scala किताब में पढ़ा है कि:का असली उदाहरण "क्या कुछ 'के लिए' कुछ 'का उपयोग` _` के समतुल्य उपयोग से बदला जा सकता है? "

अस्तित्व प्रकार भाषा की एक पूरी तरह से समर्थित हिस्सा हैं, लेकिन व्यवहार में वे मुख्य रूप से जब स्काला से जावा प्रकार तक पहुँचने किया जाता है। मैं स्काला परियोजना बनाया है और उसमें जावा एक संदर्भित:

स्काला:

object Main { 
    def main(args: Array[String]): Unit = { 
    type Test = java.util.Collection[T] forSome { type T } 
    val contents: Test = (new Wild).contents 

    type Test2 = java.util.Collection[_] 
    val contents2: Test2 = (new Wild).contents 

    // foo((new Wild).contents2) // won't compile 

    foo1((new Wild).contents2) 
    foo1((new Wild).contents3) 

    foo2((new Wild).contents3) 
    } 

    def foo(xs: java.util.Map[T, T] forSome { type T }) {} 
    def foo1(xs: java.util.Map[_, _]) {} 
    def foo2(xs: java.util.Map[_, _ <: java.lang.Number]) {} 
} 

जावा:

public class Wild { 
    public Collection<?> contents() { 
     return null; 
    } 
    public Map<?, ?> contents2() { 
     return null; 
    } 
    public Map<?, ? extends Number> contents3() { 
     return null; 
    } 
} 

सभी मामलों के साथ मैं "" forSome "की जगह करने में सक्षम था में _ "। तो वास्तविक मामले क्या हैं जहां "के लिए कुछ" आवश्यक है? कृपया सरल कामकाजी उदाहरण प्रदान करें।

उत्तर

10

यहां बल्कि सरल उदाहरण है।

val listOfSets: List[Set[T]] forSome { type T } = List(Set(1, 2, 3), Set(4, 5, 6)) 

ध्यान दें कि मैं केवल सूची में ही निहित प्रकार के सेट स्टोर कर रहा हूँ। मैं नहीं कर सकता इस:

val listOfSets: List[Set[T]] forSome { type T } = List(Set(1, 2, 3), Set("a", "b", "c")) 

listOfSets के प्रकार forSome बिना inexpressable है। दरअसल,

val listOfSets2: List[Set[_]] 

val listOfSets2: List[Set[T] forSome { type T }] 

के बराबर है और इसका मतलब है कि सूची अलग प्रकार के सेट शामिल कर सकते हैं, इसलिए इन काम के दोनों:

val listOfSets2: List[Set[_]] = List(Set(1, 2, 3), Set(4, 5, 6)) 
val listOfSets2: List[Set[_]] = List(Set(1, 2, 3), Set("a", "b", "c")) 

यह दिलचस्प है कि यदि आप स्केल दुभाषिया को scala -feature के रूप में चलाते हैं और इस उत्तर से कोड की पहली पंक्ति निष्पादित करने का प्रयास करते हैं, तो आपको बिल्कुल एक चेतावनी मिलेगी वाइल्डकार्ड के साथ अस्तित्व प्रकार के nexpressability:

scala> val listOfSets: List[Set[T]] forSome { type T } = List(Set(1, 2, 3), Set(4, 5, 6)) 
<console>:7: warning: the existential type List[Set[T]] forSome { type T }, which cannot be expressed by wildcards, should be enabled 
by making the implicit value scala.language.existentials visible. 
This can be achieved by adding the import clause 'import scala.language.existentials' 
or by setting the compiler option -language:existentials. 
See the Scala docs for value scala.language.existentials for a discussion 
why the feature should be explicitly enabled. 
     val listOfSets: List[Set[T]] forSome { type T } = List(Set(1, 2, 3), Set(4, 5, 6)) 
            ^
listOfSets: List[Set[T]] forSome { type T } = List(Set(1, 2, 3), Set(4, 5, 6)) 

एक और उदाहरण है। मान लीजिए कि आप कक्षा को उस वर्ग के एक उदाहरण में मैप करना चाहते हैं। यह इस प्रकार के साथ व्यक्त किया जा सकता है:

val classInstanceMap: Map[Class[T], T] forSome { type T } 

forSome बिना आप सही प्रकार बाहर नहीं लिख सकते हैं - वहाँ कोई दूसरा रास्ता कुंजी और मूल्यों के प्रकार "से संबंधित" है।उदाहरण के लिए, वाइल्डकार्ड के साथ इस प्रकार:

val invalidClassInstanceMap: Map[Class[_], _] 

val invalidClassInstanceMap: Map[Class[K] forSome { type K }, V] forSome { type V } 
यहाँ

K और V के बराबर है सब पर संबंधित नहीं हैं, इसके अलावा, चाबियाँ मनमाने ढंग से T के लिए Class[T] की मनमानी उदाहरण हो सकता है, लेकिन सभी मूल्यों का एक ही प्रकार होना चाहिए।

+0

धन्यवाद! यह अभी के लिए स्पष्ट है। – user4298319

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

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