問題タブ [value-class]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
scala - 暗黙の値クラスのエレガントなグループ化
私は、既存のJavaライブラリー用の暗黙のScalaラッパー・クラスのセットを作成しています (そのライブラリーを装飾して、 Scala開発者にとってより便利なものにすることができます)。
簡単な例として、Javaライブラリ (私は変更できません) に次のようなクラスがあるとします。
ここで、このクラスをScalaスタイルのゲッターとセッターで装飾したいとしましょう。これは、次の暗黙のクラスで行うことができます。
このimplicit
キーワードは、ScalaValue
コンパイラーに、 のインスタンスを のインスタンスにRichValue
暗黙的に変換できることを伝えます (後者がスコープ内にある場合)。これで、内で定義されたメソッドRichValue
を のインスタンスに適用できるようになりValue
ました。例えば:
(これはあまり良いコードではなく、正確に機能するわけでもありません。単純な使用例を示しているだけです。)
残念ながら、Scalaimplicit
ではクラスをトップレベルにすることは許可されていないためpackage object
、. (この制限が必要な理由はわかりませんが、暗黙の変換関数との互換性のためだと思います。)object
class
trait
package
ただし、これを値クラスRichValue
にするためにからも拡張しています。それらに慣れていない場合は、Scalaコンパイラーが割り当ての最適化を行うことができます。特に、コンパイラは常に のインスタンスを作成する必要はなく、値クラスのコンストラクタ引数を直接操作できます。AnyVal
RichValue
言い換えれば、Scala の暗黙的な値クラスをラッパーとして使用することによるパフォーマンスのオーバーヘッドはほとんどなく、これは素晴らしいことです。:-)
ただし、値クラスの主な制限は、class
またはtrait
;内で定義できないことです。package
s、package object
s、またはs のメンバーにしかなれませんobject
。(これは、外部クラス インスタンスへのポインタを維持する必要がないようにするためです。)
暗黙の値クラスは両方の制約セットを尊重する必要があるため、package object
または内でのみ定義できますobject
。
そしてそこに問題があります。私がラップしているライブラリには、膨大な数のクラスとインターフェースを持つパッケージの深い階層が含まれています。import
理想的には、次のような単一のステートメントで
ラッパー クラスをインポートできるようにしたいと考えています。
それらをできるだけ簡単に使用できるようにします。
これを達成するために私が現在確認できる唯一の方法は、すべての暗黙的な値クラス定義を 1つのソース ファイル内の 1
つのpackage object
(または) 内に配置することです。object
import
ただし、これは理想とはほど遠いものであり、ターゲット ライブラリのパッケージ構造をミラーリングしながら、1 つのステートメントですべてをスコープに含めたいと考えています。
このアプローチの利点を犠牲にすることなく、これを達成する簡単な方法はありますか?
(たとえば、これらのラッパーを値クラスtrait
にするのをやめると、コンポーネント パッケージごとに 1 つずつ、多数の異なる s 内でそれらを定義し、ルートpackage object
にそれらすべてを拡張させて、単一のインポートしますが、利便性のためにパフォーマンスを犠牲にしたくありません。)
scala - 構造的改良の結果タイプは、ユーザー定義の値クラスを参照できない場合があります
Wrapper を値クラスとして定義すると (AnyVal を拡張):
wrapperHolder のコンパイル エラーは次のとおりです。
- 値クラスで機能しないのはなぜですか?
scala - AnyVal ケース クラス (Seq[T <: AnyVal]) のシーケンスを実行時の表現に効率的に変換する
値ケースクラスがあると仮定します
およびこの値ケース クラスを含むシーケンス
Int
これらの値を、シーケンスを反復処理する必要なしに変換する方法はありますか (たとえば、 Seq(Id(1), Id(2), Id(3)).map(_.i)
?
私が尋ねる理由は、値ケース クラスの良いところは、実行時にネイティブ型を持つ値クラスを表現として使用できるため、非常に効率的であると思うからです。しかし、使用中のすべてのライブラリがこれらのクラスの自動「変換」をサポートしているわけではありません。したがって、ネイティブ型を渡す必要がありますが、コンパイラが最適化できるため、単純な属性の場合は大したことではありません。しかし、シーケンスがある場合は明示的にマップする必要があります。つまり、実際には実行時に同じ値にマッピングするだけなので、すべての値に対して不要な反復が発生します。そのような場合にそれを回避し、コンパイラの最適化を使用する方法はありますか?