java - 違い - scala 特徴




Scalaコレクションの標準的なプラクティス (3)

ListとSeqはscala.collectionではなくパッケージスカラーで定義されているのはなぜですか(Seqの実装はコレクションのサブパッケージに含まれています)。

それらは、scala.Predefの同義語を介して自動的にすべてのプログラムにインポートされるので、一般的に有用とみなされるからです。

コレクションを初期化してフリーズするための標準的なメカニズムは何ですか(Javaでは変更不可能なものをラップすることによって達成されます)。

Javaには、コレクションをフリーズするメカニズムはありません。 例外をスローするラッパーに(まだ変更可能な)コレクションをラップするためのイディオムしかありません。 Scalaの適切なイディオムは、変更可能なコレクションを不変のものにコピーすることです - 恐らく:_ *

一部のコレクションタイプ(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")}をinitとして記述し、問題をすべて保存して、コンストラクタvar mySet : ISet[String] = Set("Hello", "World")入れてvar mySet : ISet[String] = Set("Hello", "World")

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の多彩なオプションに悩まされていることを告白する必要があります。 がある:

  • scala.List (およびSeq
  • scala.collections.Set (およびMap
  • scala.collection.immutable.Set (およびMapStackではなくList
  • scala.collection.mutable.Set (およびMapBufferではなくList
  • scala.collection.jcl

だから質問!

  1. ListSeqscala.collectionではなくパッケージSeq定義されているのはなぜですか( Seq実装はコレクションのサブパッケージに含まれています)。
  2. コレクションを初期化しフリーズするための標準的なメカニズムは何ですか(Javaではunmodifiableものをラップすることによって達成されます)。
  3. 一部のコレクションタイプ( MultiMap )が変更可能なものとしてのみ定義されているのはなぜですか? (不変のMultiMapはありません)?

ダニエル・スピワックの優れたスカラコレクションシリーズを読んだことがありますが、実際にそれらを実際にどのように使用するのかというのはまだ困惑しています。 完全なパッケージ宣言の実施により、以下はやや扱いにくいようです。

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ラッパーの下で変更される可能性があります)


いくつかのランダムな考え方:

  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" ) )
  }
}

私は最近、オフィスの周りで涙が出てきました。 「ヌルは悪です!」


現在のバージョンのScalaコレクションAPIには矛盾があるかもしれないことに注意してください。 Scala 2.8(2009年後半にリリース予定)では、コレクションAPIをより一貫性と柔軟性を持たせるためにオーバーホールしています。

ScalaのWebサイトhttp://www.scala-lang.org/node/2060この記事を参照してhttp://www.scala-lang.org/node/2060

lateBoundSetを使用してTristan Juricekのサンプルに追加するには:Scalaには、「lazy」キーワードを使用して遅延初期化のメカニズムが組み込まれています。

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

こうすることで、新しいMyClassインスタンスを作成する直前ではなく、最初の使用時にmySetが初期化されます。





scala-collections