4

私が理解している限り、Scalaの値クラスは、追加のメモリ使用量を導入することなく、プリミティブ型を別の型のようにInt、または別の型にラップするためのものです。Booleanしたがって、これらは基本的に通常のクラスの軽量な代替手段として使用されます。

newtypeこれは、既存の型を新しい型にラップするためにも使用されるHaskellの表記法を思い出させます。したがって、追加のスペースを消費することなく、一部のデータに新しいインターフェイスを導入します(両方の言語の類似性を確認するには、たとえば、1つの「コンストラクター」と1つの「コンストラクター」への制限を考慮してください。 HaskellScalaの両方のフィールド)。

私が疑問に思っているのは、コンパイラーによってインライン化される新しい型を導入するという概念が、あらゆる種類の型に対してオーバーヘッドがゼロの型ラッパーを持つというHaskellのアプローチに一般化されていない理由です。なぜScalaの人たちはAnyValここでプリミティブ型(別名)に固執したのですか?

それとも、Scalaにそのような型のラッパーを定義する方法はすでにありScala.AnyRefますか?

4

2 に答える 2

12

に限定されませんAnyVal

implicit class RichOptionPair[A,B](val o: Option[(A,B)]) extends AnyVal {
  def ofold[C](f: (A,B) => C) = o map { case (a,b) => f(a,b) }
}

scala> Some("fish",5).ofold(_ * _)
res0: Option[String] = Some(fishfishfishfishfish)

値クラスには軽量ラッパーのように振る舞うさまざまな制限がありますが、プリミティブをラップできることだけが制限の 1 つではありません。

于 2012-12-08T18:58:02.733 に答える
2

推論はScala改善プロセス(SIP)-15として文書化されています。Alexey Romanovがコメントで指摘したように、このアイデアは、コンパイラがこの状況を判断できるようにする既存のキーワードを使用して式を探すことでした。

コンパイラがインライン化を実行するために、ラッピングクラスが「エフェメラル」(フィールドまたはオブジェクトメンバー、コンストラクター本体などがない)であるなど、いくつかの制約が適用されます。インライン化クラスを自動的に生成するという提案には、少なくとも2つの問題があります。

  1. コンパイラーは、各クラスの制約のリスト全体を調べる必要があります。また、値クラスとしてのステータスは暗黙的であるため、後でクラスにメンバーを追加することで反転し、バイナリ互換性が失われる可能性があります
  2. コンパイラによってさらに制約が追加されます。たとえば、値クラスがfinal継承を禁止するようになります。したがって、これらの制約をそのようにインライン化できるようにしたいクラスに追加する必要があります。そうすれば、余分な冗長性しか得られません。

たとえば、他の架空の構成を考えることもできますが、IMOval class Meter(underlying: Double) { ... }の利点はextends AnyVal、構文拡張が不要なことです。また、すべてのプリミティブ型が拡張AnyValされているため、優れたアナロジーがあります(参照なし、継承なし、効果的な表現など)。

于 2012-12-09T09:18:40.087 に答える