2009-03-23 17 views
31

एक Java पृष्ठभूमि से आ रहा है, मैं संग्रह से निपटने का आम बात करने के लिए इस्तेमाल कर रहा हूँ: स्पष्ट रूप से कुछ अपवाद हो सकता है लेकिन आम तौर पर कोड दिखाई देगा:स्काला संग्रह मानक अभ्यास

public class MyClass { 
    private Set<String> mySet; 

    public void init() { 
    Set<String> s = new LinkedHashSet<String>(); 
    s.add("Hello"); 
    s.add("World"); 
    mySet = Collections.unmodifiableSet(s); 
    } 
} 

मैं कबूल करना है कि है मैं स्कैला में विकल्पों के काफी हद तक परेशान हूं। नहीं है:

  • scala.List (और Seq)
  • scala.collections.Set (और Map)
  • scala.collection.immutable.Set (और Map, Stack नहीं बल्कि List)
  • scala.collection.mutable.Set (और Map, Buffer नहीं बल्कि List)
  • scala.collection.jcl

तो प्रश्न!

  1. क्यों List और Seq पैकेज scala में परिभाषित कर रहे हैं और नहीं scala.collection (भले ही Seq के कार्यान्वयन संग्रह उप संकुल में हैं)?
  2. क्या के लिए मानक तंत्र आरंभ कर रहा है एक संग्रह और फिर ठंड यह (जो जावा में पूरा हो जाने पर unmodifiable में लपेटकर द्वारा)?
  3. कुछ संग्रह प्रकार क्यों हैं (उदा। MultiMap) केवल म्यूटेबल के रूप में परिभाषित किया गया है? (कोई अपरिवर्तनीय MultiMap नहीं है)?

मैंने डैनियल स्पिवाक के excellent series on scala collections पढ़ा है और अभी भी इस बात से परेशान हूं कि वास्तव में अभ्यास में उनका उपयोग कैसे किया जाएगा। निम्नलिखित लागू की पूर्ण पैकेज घोषणाओं की वजह से थोड़ा बोझल लगता है:

class MyScala { 
    var mySet: scala.collection.Set[String] = null 

    def init(): Unit = { 
    val s = scala.collection.mutable.Set.empty[String] 
    s + "Hello" 
    s + "World" 
    mySet = scala.collection.immutable.Set(s : _ *) 

    } 
} 

हालांकि यकीनन इस अधिक सही जावा संस्करण के रूप में अपरिवर्तनीय संग्रह (जावा मामले में, जहां अंतर्निहित संग्रह सकता है के रूप में नहीं बदल सकते हैं की तुलना में है नीचे unmodifiable आवरण बदला जा)

उत्तर

26

क्यों सूची और Seq पैकेज स्केला में परिभाषित कर रहे हैं और नहीं scala.collection (भले ही Seq के कार्यान्वयन संग्रह उप संकुल में हैं)?

क्योंकि उन्हें आमतौर पर उपयोगी माना जाता है कि वे स्वचालित रूप से scala.Predef में समानार्थी के माध्यम से सभी प्रोग्रामों में आयात किए जाते हैं।

संग्रह शुरू करने के लिए मानक तंत्र क्या है और फिर इसे फ्रीज करना (जिसे जावा में एक अपरिवर्तनीय में लपेटकर हासिल किया जाता है)?

जावा में संग्रह को जमा करने के लिए कोई तंत्र नहीं है। इसमें एक अपवाद फेंकने वाले रैपर में (अभी भी संशोधित) संग्रह लपेटने के लिए केवल एक मुहावरे है।_ *

क्यों कुछ संग्रह प्रकार (उदा मल्टीमैप) केवल अस्थायी रूप में परिभाषित कर रहे हैं: शायद का उपयोग कर - स्काला में उचित मुहावरा अपरिवर्तनीय एक में एक परिवर्तनशील संग्रह कॉपी करने के लिए है? (कोई अपरिवर्तनीय मल्टीमैप नहीं है)?

टीम/समुदाय अभी तक अभी तक नहीं मिला है। 2.7 शाखा में जोड़ों का एक समूह देखा गया और 2.8 से अधिक गुच्छा होने की उम्मीद है।

निम्नलिखित लागू की पूर्ण पैकेज घोषणाओं की वजह से थोड़ा बोझल लगता है:

यह हमेशा इस संबंध में जावा की तुलना में कम है, इसलिए वर्बोज़ (उदाहरण के java.util.Date और जावा के लिए देख स्काला आयात उपनाम की अनुमति देता है .sql.Date - पूरी तरह से योग्य होने के लिए)

import scala.collection.{Set => ISet} 
import scala.collection.mutable.{Set => MSet} 

class MyScala { 
    var mySet: ISet[String] = null 

    def init(): Unit = { 
    val s = MSet.empty[String] 
    s + "Hello" 
    s + "World" 
    mySet = Set(s : _ *) 
    } 
} 
बेशक

दोनों बलों एक का उपयोग कर, आप वास्तव में सिर्फ init def init() { mySet = Set("Hello", "World")} के रूप में बेहतर अभी तक लिख सकते हैं और सब मुसीबत सहेजते हैं, या सिर्फ निर्मातामें रख 10

+1

मैं अनुमान लगा रहा हूं कि कुछ मूल्यों के माध्यम से लूपिंग और इसे सेट में जोड़ना, बजाय मूल्यों के समूह के बजाय। – runT1ME

4

यादृच्छिक विचारों के एक जोड़े:

  1. मैं null का उपयोग कभी नहीं, मैं Option है, जो तब एक सभ्य त्रुटि टॉस होगा का उपयोग करें। इस अभ्यास को टनNullPointerException अवसरों से छुटकारा मिला है, और लोगों को सभ्य त्रुटियां लिखने के लिए मजबूर करता है।
  2. "म्यूटेबल" सामानों को देखने से बचने की कोशिश करें जब तक कि आपको वास्तव में इसकी आवश्यकता न हो।

तो, अपने स्केला उदाहरण पर मेरी बुनियादी ले, जहाँ आप प्रारंभ करने में बाद में सेट है,

class MyScala { 
    private var lateBoundSet:Option[ Set[ String ] ] = None 
    def mySet = lateBoundSet.getOrElse(error("You didn't call init!")) 

    def init { 
    lateBoundSet = Some(Set("Hello", "World")) 
    } 
} 

मैं कार्यालय के आसपास हाल ही में एक आंसू पर किया गया है है। "शून्य बुरा है!"

3

ध्यान दें कि मौजूदा संस्करण में स्कैला संग्रह API में कुछ असंगतताएं हो सकती हैं; स्कैला 2.8 (बाद में 200 9 में रिलीज होने के लिए), संग्रह एपीआई को अधिक सुसंगत और अधिक लचीला बनाने के लिए इसे ओवरहाल किया जा रहा है।

स्काला वेबसाइट पर इस लेख देखें: http://www.scala-lang.org/node/2060

एक lateBoundSet साथ ट्रिस्टन Juricek के उदाहरण के लिए जोड़ने के लिए: स्काला, आलसी आरंभीकरण के लिए एक अंतर्निहित तंत्र है "सुस्त" कीवर्ड का उपयोग:

class MyClass { 
    lazy val mySet = Set("Hello", "World") 
} 

ऐसा करने से, मेरा नया सेट पहली बार माइक्रोसैस उदाहरण बनाते समय तुरंत उपयोग किया जाएगा।

7

उत्परिवर्ती संग्रह कभी-कभी उपयोगी होते हैं (हालांकि मैं मानता हूं कि आपको हमेशा अपरिवर्तनीय लोगों को हमेशा देखना चाहिए)। उनका इस्तेमाल करते हैं, तो मैं

import scala.collection.mutable 
फ़ाइल के शीर्ष पर (उदाहरण के लिए)

, और लिखने के लिए करते हैं:

val cache = new mutable.HashMap[String, Int] 
मेरी कोड में

। इसका मतलब है कि आपको केवल "mutable.HashMap" लिखना है, स्कैला नहीं।collection.mutable.HashMap "। उल्लेख ऊपर कमेंटेटर के रूप में, आप नाम आयात में पुन: मैप सकता है (जैसे, "आयात scala.collection.mutable {HashMap => mmap}।"), लेकिन:

  1. मैं पसंद के नाम वध करने के लिए नहीं, ताकि यह स्पष्ट हो कि मैं किस वर्ग का उपयोग कर रहा हूं, और
  2. मैं शायद 'उत्परिवर्तनीय' का उपयोग करता हूं जो कि मेरे स्रोत में "mutable.ClassName" होने से अनावश्यक बोझ नहीं है।

(इसके अलावा, मैं गूंज कर सकते हैं भी टिप्पणी 'nulls से बचने के'। यह कोड इतना अधिक मजबूत और सुबोध बनाता है। मुझे लगता है कि मैं भी उतना ही विकल्प का उपयोग करने के लिए के रूप में आप या तो उम्मीद थी की जरूरत नहीं है ।)

+0

मुझे नामकरण सम्मेलन पसंद है। आपको इसे यहां योगदान देना चाहिए: http://groups.google.com/group/liftweb/browse_thread/thread/4460656773dc8729/47359c9e7cd08c80 – Trenton

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

  • कोई संबंधित समस्या नहीं^_^