0

ZeroMQ および Akka と統合して、異なるインスタンスからケース クラスを送信しています。問題は、このコードをコンパイルしようとしたときです:

def persistRelay(relayEvent:String, relayData:Any) = {
    val relayData = ser.serialize(relayData).fold(throw _, identity)
    relayPubSocket ! ZMQMessage(Seq(Frame(relayEvent), Frame(relayData)))
  } 

Scala コンパイラは をスローしますrecursive value relayData needs type

入ってくるケースクラスはすべて異なっており、似Team(users:List[Long], teamId:Long)ています。

シリアライザーまたは回避策で任意の型を許可する方法はありますか? 絶対に必要でない限り、データを作成するすべての関数に対してシリアライザーを作成することは避けたいと思います。

ありがとう!

4

1 に答える 1

3

これは実際にはタイピングの問題ではありません。問題は:

val relayData = ser.serialize(relayData).fold(throw _, identity)

val relayDataメソッド parameter への参照を作成しているのと同じ行でa を宣言していますrelayData。Scala コンパイラは、同じ名前の 2 つの変数がある/必要であることを理解せず、代わりに、それを の再帰的な定義として解釈しval relayDataます。これらの変数のいずれかの名前を変更すると、エラーが修正されます。

いずれにせよ、あなたは Scala コンパイラーが求めていたことに完全に従わなかったので、コンパイラーがあなたに何を求めていたのかについて、あなたに記入するのも良いと思います (たとえ従うならば、おそらく、状況を考えると、あまり意味がないように見えるさらに別のエラーが発生する可能性があります)。

「再帰値relayDataには型が必要」と言われました。relayDataこれの意味は、次のようにして の型を単純に指定してほしいということです。

val relayData = ...

のようなものになる

val relayData: Serializable = ...

(または、の代わりにSerializable、必要なタイプを使用relayDataします)

再帰的な定義を作成するには、この情報が必要です。たとえば、次の単純なケースを考えてみましょう。

val x = x + 1

このコードは...控えめに言っても奇妙ですが、私がやっていることはx(浅い)再帰的な方法で定義しています。しかし、問題があります: コンパイラはどのようにして inner に使用する型を知ることができるのxでしょうか? 型推論は他の定義の型情報を利用することを含み、この定義はx型情報を必要とするため、型推論によって型を実際に決定することはできません。さて、はおそらく について話していると推測できるかもしれませんIntが、理論的にxは、非常に多くのについて話している可能性があります! 実際、これが動作中のあいまいさです。

val x: Int = x + 1 // Default value for an Int is '0'
x: Int = 1

val y: String = y + 1 // Default value for a String is 'null'
y: String = null1

実際に変更されたのは型注釈だけですが、結果は大幅に異なります。これは非常に単純なケースにすぎません! ええ、これをすべて要約すると...ほとんどの場合、型が必要な再帰的な値について不平を言っているときは、貧弱なコンパイラにある程度の共感を持ち、それが切望する型情報を与える必要があります。DeLongey さん、あなたにも同じことが起こります。それはあなたにとっても同じことです!

于 2012-05-25T17:17:49.193 に答える