9

コールバックベースのスタイルを使用してプロプライエタリバスに接続して通信するためのJavaAPIが提供されました。私は現在、概念実証アプリケーションをscalaに実装しており、もう少し慣用的なscalaインターフェイスを作成する方法を模索しています。

典型的な(簡略化された)アプリケーションは、Javaでは次のようになります。

    DataType type = new DataType();
    BusConnector con = new BusConnector();
    con.waitForData(type.getClass()).addListener(new IListener<DataType>() {
        public void onEvent(DataType t) {
            //some stuff happens in here, and then we need some more data
            con.waitForData(anotherType.getClass()).addListener(new IListener<anotherType>() {
                public void onEvent(anotherType t) {
                    //we do more stuff in here, and so on
                }
            });
        }
    });

    //now we've got the behaviours set up we call
    con.start();

Scalaでは、(T => Unit)からIListenerへの暗黙の変換を明らかに定義できます。これにより、物事が少し読みやすくなります。

implicit def func2Ilistener[T](f: (T => Unit)) : IListener[T] = new IListener[T]{
  def onEvent(t:T) = f
}

val con = new BusConnector
con.waitForData(DataType.getClass).addListener( (d:DataType) => {
  //some stuff, then another wait for stuff
  con.waitForData(OtherType.getClass).addListener( (o:OtherType) => {
    //etc
  })
})

これを見ると、scalazの約束とf#非同期ワークフローの両方を思い出しました。

私の質問はこれです:

これを理解のために、または同様に慣用的なものに変換できますか(これは俳優にもかなりうまくマッピングされるべきだと思います)

理想的には、次のようなものを見たいです。

for(
  d <- con.waitForData(DataType.getClass);
  val _ = doSomethingWith(d);
  o <- con.waitForData(OtherType.getClass)
  //etc
)
4

2 に答える 2

6

これに理解を使用したい場合は、for理解の拡張方法について、Scala言語仕様を確認することをお勧めします。これmapにより、flatMapこの構造がすでに持っているものとどのように関連しているかについての手がかりが得られます(へのネストされた呼び出しを使用しaddListenerます。次に、に委任する適切な、、などのメソッドを使用して、waitForData呼び出しの戻り型から新しい型への暗黙的な変換を追加できます。mapflatMapaddListener

アップデート

scala.Responder[T]標準ライブラリから使用できると思います。

addListenerを持つクラスが呼び出されると仮定しDispatcher[T]ます:

trait Dispatcher[T] {
  def addListener(listener: IListener[T]): Unit
}

trait IListener[T] {
  def onEvent(t: T): Unit
} 

implicit def dispatcher2Responder[T](d: Dispatcher[T]):Responder[T] = new Responder[T} {
  def respond(k: T => Unit) = d.addListener(new IListener[T] {
    def onEvent(t:T) = k
  })
}

その後、要求に応じてこれを使用できます

for(
  d <- con.waitForData(DataType.getClass);
  val _ = doSomethingWith(d);
  o <- con.waitForData(OtherType.getClass)
  //etc
) ()

Cometチャットアプリケーションの使用については、 Scalawikiこのプレゼンテーションを参照してください。Responder[T]

于 2010-04-24T19:35:46.743 に答える
3

私はScalaの経験がほとんどありませんが、このようなものを実装する場合は、コールバックリスナークラスを使用するのではなく、アクターメカニズムを活用することを検討します。アクターは非同期通信用に作成されており、アプリのさまざまな部分を適切に分離します。複数のリスナーにメッセージを送信させることもできます。

ただし、「本物の」Scalaプログラマーがこのアイデアを具体化するのを待つ必要があります。;)

于 2010-04-24T16:18:21.327 に答える