2009-03-23 2 views
31

Исходя из Java фона, я привык к общей практике работы с коллекциями: очевидно, не будет исключения, но, как правило, код будет выглядеть следующим образом:коллекция Scala стандартная практика

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. Существует:

  • scala.ListSeq)
  • scala.collections.SetMap)
  • scala.collection.immutable.SetMap, Stack но не List)
  • scala.collection.mutable.SetMap, Buffer но не List)
  • scala.collection.jcl

Так что вопросы!

  1. Почему List и Seq определены в пакете scala и не scala.collection (даже если реализации Seq находятся в коллекции суб-пакетов)?
  2. Что стандартный механизм для инициализации коллекции, а затем замораживание он (который в Java достигается путем оборачивания в 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 : _ *) 

    } 
} 

Хотя, возможно, это правильнее чем версия Java, как неизменная коллекция не может измениться (как в случае Java, где базовая коллекция МОГЛА может быть изменен под unmodifiable обертке)

ответ

26

Почему Перечень и Seq определены в пакете Скале и не scala.collection (даже если реализации послед находятся в коллекции суб-пакетов)?

Потому что они считаются настолько полезными, что они автоматически импортируются во все программы через синонимы в scala.Predef.

Каков стандартный механизм инициализации коллекции, а затем ее замораживания (что в Java достигается путем переноса в немодифицируемую)?

В Java нет механизма для замораживания коллекции. У него есть только идиома для обертывания (все еще модифицируемой) коллекции в оболочке, которая генерирует исключение.Правильная идиома в Scala заключается в том, чтобы скопировать изменчивую коллекцию в неизменяемую, возможно, используя: _ *

Почему некоторые типы коллекций (например, MultiMap) определяются только как изменяемые? (Нет неизменяемой MultiMap)?

Команда или сообщество еще не получили ее еще. В филиале 2,7 было добавлено множество дополнений, и ожидается, что 2,8 будет больше.

Следующие кажется немного громоздким из-за насильственными полные декларации пакета:

Scala позволяет импортировать псевдонимы, так что всегда компактнее, чем Java в этом отношении (например, см java.util.Date и Java .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 : _ *) 
    } 
} 

конечно, вы на самом деле просто написать инициализации, как def init() { mySet = Set("Hello", "World")} и сохранить все неприятности или еще лучше просто положить его в конструктор var mySet : ISet[String] = Set("Hello", "World")

+1

Я предполагаю, что он более вероятно, что что-то перебирает что-то и добавляет его в набор, а не только группу значений. – runT1ME

4

Несколько случайных мыслей:

  1. Я никогда не использую null, я использую Option, который затем подбрасывать приличную ошибку. Эта практика избавилась от возможностей tonNullPointerException и заставила людей писать приличные ошибки.
  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 коллекций Scala в текущей версии; для Scala 2.8 (который будет выпущен позднее в 2009 году), API-интерфейс коллекций пересматривается, чтобы сделать его более последовательным и более гибким.

Смотрите эту статью на сайте Scala: http://www.scala-lang.org/node/2060

Чтобы добавить к примеру Тристана Juricek в с lateBoundSet: Scala имеет встроенный механизм для отложенной инициализации, используя «ленивое» ключевое слово:

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

Таким образом, mySet будет инициализирован при первом использовании, а не сразу при создании нового экземпляра MyClass.

7

Удобные коллекции полезны иногда (хотя я согласен, что вы всегда должны смотреть на неизменяемые). Если использовать их, я стараюсь писать

import scala.collection.mutable 

в верхней части файла, и (к примеру):

val cache = new mutable.HashMap[String, Int] 

в моем коде. Это означает, что вам нужно написать «mutable.HashMap», а не scala.collection.mutable.HashMap». Как комментатора выше, вы можете переназначить имя в импорте (например, «импорт scala.collection.mutable {HashMap => MMap}.»), Но:

  1. Я предпочитаю не искажать имена, так что яснее, какие классы я использую, и
  2. Я использую «изменчивый» достаточно редко, поскольку наличие «mutable.ClassName» в моем источнике не является избыточным бременем для .

(Кроме того, могу ли я повторить комментарий «избегать ошибок», что делает код более надежным и понятным. Я считаю, что мне даже не нужно использовать параметр столько, сколько вы ожидали бы .)

+0

Мне нравится это соглашение об именах. Вы должны внести свой вклад здесь: http://groups.google.com/group/liftweb/browse_thread/thread/4460656773dc8729/47359c9e7cd08c80 – Trenton