問題タブ [case-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 - ネットワーク上のAkkaを使用したScalaケースクラスとプロトコルバッファ
最初に少しコンテキスト:私はScala(ファーストパーソンシューティングゲームのような)でクライアント/サーバーゲームを書いています。クライアントは1秒間に数十回サーバーに移動の意図を送信する必要があり、サーバーはエンティティの状態を送り返します。リアルタイムでも。クライアント側(グラフィカルな流動性のため)とサーバー側の両方でJBulletを使用して、これらのエンティティの物理シミュレーションがあります。クライアントがサーバーから更新を受信するたびに、クライアントはそのローカル状態をサーバーが送信した状態に置き換えます。もちろん、特定の瞬間に同じサーバー上に多くのクライアントが存在する可能性があります。要するに、このアプリケーションでは、通信は小さなパケットで頻繁に発生します。
現在、私はAkkaのアクターを使用して、Scalaケースクラスをネットワーク経由でサーバーに素朴に送受信しています。次に例を示します。
次に、クライアントで:
サーバー上:
ent.stateがEntityStateを返す場合:
これはすべてかなりうまく機能していますが、ご覧のとおり、他のケースクラスを含むケースクラスがたくさんあり、クライアントとサーバーの両方で一連のケーステストがあります。
- シリアル化、逆シリアル化、およびマッチングによるパケットサイズとオーバーヘッドの両方を削減するにはどうすればよいですか?
- ケースクラスの代わりにProtobufを使用すると、アプリケーションのパケットから脂肪が削減されますか?
- このネットワークプロトコルの改善のために間違った場所を見ていますか?
scala - シリアライゼーション下でのケース オブジェクトの同一性/パターン マッチングの修正
セッションでシリアル化および逆シリアル化されるクラスがあり、内部クラスでパターン マッチングを実行する必要があります。内部クラスの識別に問題があります:
EmptyValue
いわば「パスの依存関係をエスケープ」しないようにアイデンティティを修正するエレガントな方法は何ですか。シリアル化が行われているときに壊れる次のようなコードがあります。
つまり、コンパイラは私の一致が完全であると言いますが、シリアライゼーションを使用するとランタイムMatchError
が発生します(バイト配列に書き込み/読み取りを行うカスタムコードがあります)。たとえば、ツリー内からTree$EmptyValue$@4636
a を取得して呼び出していますがTree$EmptyValue$@3601
、それらは一致しません。
編集
内部型を外に移動する必要がないようにしたいので、さらにテストを実施しました。型パラメーターが必要になるため、すべてのパターン マッチング コードが壊れてしまうからです。問題はその特定のものでのみ発生するように見えますcase object
:
scala - バインドされていない型パラメーターを持つメンバーでケース クラスを定義する方法は?
バインドされた型パラメーターを持つクラス定義が与えられた場合、Scala コンパイラーはからAnimal[A <: String]
推論しないようです。推論は許されますか?コンパイラが推論を行うのを助ける方法は?B <: String
Animal[B]
以下は、この推論の欠如が問題となるケース クラスの具体的な例です。
次のケース クラス階層を考えてみましょう。
たとえばUniversity
、型の変数でインスタンス化できるケース クラスを定義する必要があります。これは次の定義で機能すると思いました。Person[_]
val p: Person[_] = Student()
しかし、これはエラーでコンパイルに失敗します:
ケースクラスの型パラメーターをバインドすると、University
コンパイルされます(キーワードをドロップすると、無制限のパラメーターでもコンパイルされますcase
が、これは私の場合のオプションではありません):
しかし、このパラメータ化されたバージョンは、タイプ の無制限の変数でインスタンス化することはできませんPerson[_]
:
コンパイルに失敗します:
次のようなバインドされた引数を持つメソッドでも同じエラーが発生します。
したがって、これはクラス コンストラクターに固有のものではありません。
2 つの質問:
型
Person
はパラメータ bounds で定義されるためPerson[+T <: Person[T]]
、この型の各インスタンスはこれらの境界を尊重することが保証されます。または私は何かを逃していますか?では、コンパイラが文句を言わないようにするにはどうすればよいでしょうか?val p: Person[P]
P <: Person[P]
のようなバインドされていない型パラメーターを持つメンバーでケースクラスを定義する方法/できます
case class University(p: Person[_])
か?
scala - Scalaのパターンマッチングで使用するための引数として不明なケースクラスを受け入れるメソッドを宣言する
抽象的で、一連のケースクラスを持つクラスAを想像してみてください。セットクラスの数や、それらのケースクラスの名前すらわかりません。
今私はこれを持っています:
そして、引数でcaseクラス型をメソッドに渡したい。これが必要な理由は、ファイルに一連のルールを構成するためです。そして、それらのルールをロードし、それらのルールが提供するいくつかの情報とのパターンマッチングを使用したいと思います。私はこのようなことをしたい:
これは可能ですか?
それほど簡単ではない場合、パターンマッチングで抽象クラスを使用できますか?抽象クラスはすべてのケースクラスの主要な構造を持っているので、単純に抽象クラスを使用できれば完璧です。
編集:
ケースクラスは異なる引数を持つ可能性があるため、クラスAに基づいたものを使用することをお勧めします(フィールドとのみパターンマッチングを実行できるため)
scala - 別のオブジェクトに囲まれたオブジェクトで定義されたケース クラスのフィールド名を取得する
次のように定義された2つのケースクラスがあります
そして、次のようにインスタンスのフィールド名を取得したいと思います:
これは objectouter
では期待どおりに機能しますが、 では機能しませんinner
。出力は次のとおりです。
私が見る唯一の違いは、クラスInnerCase
が別のオブジェクトで定義されたオブジェクト自体で定義されているのに対し、クラスはOuterCase
1 つのオブジェクトのみに囲まれていることです。
なぜそれが問題になるのでしょうか?ケース オブジェクトのパラメータ名を取得できるのに、なぜケース オブジェクトを取得できouter
ないのですか?inner
Scala 2.9.2 でこの動作を確認しました。
ありがとうございました!
いくつかの追加メモ
scala
同じコンパイル済みクラスをコマンド ラインから実行する場合と sbt を使用する場合では異なることに気付きました。
コマンドラインから:
しかし、sbt では:
ここで何が起こっているのかを知るためのヒントをいただければ幸いです。
scala - Scala:親クラスが子によってのみ定義されたメソッドにアクセスする方法はありますか?
抽象基本クラスから継承する2つのケースクラスがあります。継承するケースクラスのコピーメソッドを使用する(したがって、子クラスのインスタンスを返す)抽象基本クラスにいくつかのメソッドを定義したいのですが、自己型を使用してこれを行う方法はありますか?
コード例:
この質問のおかげで、私が望む結果を得る方法を理解しました: Scalaのこの型付け、抽象型などを使用してSelf型を実装するにはどうすればよいですか? ただし、makeCopyメソッドをBaseClassに追加し、各子ケースクラスでcopyを呼び出すことでオーバーライドする必要があり、構文(特にSelfタイプの場合)はかなり混乱します。Scalaに組み込まれているセルフタイピングでこれを行う方法はありますか?
scala - scala スクリプトから scalap を使用することは可能ですか?
scalap
いくつかのケース クラスのフィールド名を読み上げるために使用しています (この質問で説明されているように)。ケースクラスとそれらを分析するために使用するコードの両方scalap
がコンパイルされ、クラスパス上の jar ファイルに配置されています。
今、このコードを使用するスクリプトを実行したいので、指示に従って次のようなものを思いつきました
これは機能しません:
java.lang.ClassCastException: scala.None$ は scala.tools.nsc.interpreter.ByteCode$.caseParamNamesForPath(ByteCode. scala:45) で scala.Option にキャストできません。scala.tools.nsc.interpreter.ProductCompletion.caseNames( ProductCompletion.scala:22)
ただし、すべてをコンパイルすると、コードは正常に機能します。のような追加scala
のオプションを試してみ-savecompiled
ましたが、これは役に立ちませんでした。これはバグですか、それとも原則として機能しませんか? (もしそうなら、誰かが理由を説明できますか?私が言ったように、分析されるケースクラスscalap
はコンパイルされます。)
注: Scala 2.9.1-1 を使用しています。
編集
これが私が本質的にやろうとしていることです(ケースクラスの複数のインスタンスを作成する簡単な方法を提供します):
注: Scala 2.9.2 に移行しましたが、エラーは同じままです (おそらくバグではありません)。
scala - 特性を動的に混合する
特性を持つ
任意のケース クラスのインスタンスを受け入れ、そのトレイトが混在するコピーを返すメソッドを実装するにはどうすればよいですか?
メソッドのシグネチャは次のようになります。
scala - ケースクラスコンストラクターでの一見偽の「引数を取らない」エラー
コンストラクター用のいくつかのパラメーターを持つケース クラスがあり、次のように、別の引数セットを取る代替コンストラクターを定義する付随するクラス オブジェクトを定義します。
で元のケースクラスコンストラクターを使用したいfoldRight
:
これを行うと、コンパイラから「MyClass はパラメーターを取りません」というエラー メッセージが表示されます。セクションをコメントアウトすると、val mc2 = ...
この問題はなくなりMyClass
ますが、 の定義で明らかにパラメータを取得していますzero
。本当に基本的な何かが欠けているように感じますが、それが何であるかわかりません。の2番目の引数として使用するヘルパーメソッドまたは関数値を定義するなど、いくつかの回避策を試しましたfoldRight
が、どれも役に立ちません。基本的にランダムにいじっているので、それほど驚くことではありません。
scala - 階層が必要な場合にケース クラスを使用するには?
ケースクラスからの継承が許可されていないことは知っていますが、本当に必要な場合はどうしますか? 階層内に 2 つのクラスがあり、どちらにも多くのフィールドが含まれており、両方のインスタンスを作成できる必要があります。ここに私のオプションがあります:
- スーパークラスをケースクラスではなく通常のクラスにすると、toString、equals、hashCode メソッドなどのすべてのケースクラスの利点が失われます。
- ケースクラスのままにしておくと、ケースクラスから継承しないというルールを破ることになります。
- 子クラスでコンポジションを使用すると、多くのメソッドを記述して他のクラスにリダイレクトする必要があります。これは、多くの作業を意味し、非 Scalaish に感じられることを意味します。
私は何をすべきか?よくある問題ではないでしょうか。