2017-11-14 10 views
0

関数名を受け取るこのことは、それらのやるアッカ俳優電流Iが2行動でシンプルな俳優を持って

package com.hello 

import akka.actor.{Actor, ActorLogging} 

case object Ping 

class Hello extends Actor with ActorLogging { 

    import context._ 

    def receive: Receive = behaviorFoo 

    self ! Ping 

    def behaviorFoo: Receive = { 
    case _ => 
     log.info(this.receive.getClass.getSimpleName) 
     become(behaviorBar) 
     self ! Ping 
    } 

    def behaviorBar: Receive = { 
    case _ => 
     log.info(this.receive.getClass.getSimpleName) 
    } 
} 

:現在受信機能

変化挙動をログに記録

ピング自己

をビヘイビアバー

ping自己

それが2番目のログに "$ anonfun $ behaviorBar $ 1" ではない、なぜ受信機能

現在のログイン両方のケースで、それは "$ anonfun $ behaviorFoo $ 1"

をログに記録しますか?

私は

self ! Ping 

    def receive: Receive = { 
    case _ => 
     log.info(this.receive.getClass.getSimpleName) 
     become(behaviorFoo) 
     self ! Ping 
    } 

    def behaviorFoo: Receive = { 
    case _ => 
     log.info(this.receive.getClass.getSimpleName) 
     become(behaviorBar) 
     self ! Ping 
    } 

    def behaviorBar: Receive = { 
    case _ => 
     log.info(this.receive.getClass.getSimpleName) 
    } 

にコードを変更した場合、それは "$ anonfun $ $ 1受け取る" 3回を記録します

は、(受信)現在の行動を取得する方法を存在する関数名ですか? 、またはいつでもlog.info( "behaviorFoo")のようにハード書き込みする必要がありますか?

更新:伐採問題に関する

、私はその後、

trait MyLogging extends ActorLogging { 
    this: Actor ⇒ 

    private[this] val actorClassName = this.getClass.getSimpleName 

    private[this] var receiveName: String = { 
    val receiveClassName = s"${this.receive.getClass.getSimpleName}" 
    val left = receiveClassName.substring(0, receiveClassName.lastIndexOf("$")) 
    left.substring(left.lastIndexOf("$") + 1) 
    } 

    def become(behavior: Actor.Receive): Unit = { 
    val behaviorClassName = behavior.getClass.getSimpleName 
    val left = behaviorClassName.substring(0, behaviorClassName.lastIndexOf("$")) 

    receiveName = left.substring(left.lastIndexOf("$") + 1) 

    context.become(behavior) 
    } 

    def info(message: Any): Unit = log.info(s"$actorClassName : $receiveName got $message") 
} 

を追加し、私の俳優のコードは

class Hello extends Actor with MyLogging { 

    def receive: Receive = behaviorFoo 

    self ! Ping 

    def behaviorFoo: Receive = { 
    case any => 
     info(any) 
     become(behaviorBar) 
     self ! Ping 
    } 

    def behaviorBar: Receive = { 
    case any => info(any) 
    } 
} 

なる今こんにちは...

のようなルックスを記録します:behaviorFooはPingを持っています

...こんにちは:ビヘイビアバーはPingを持っています

答えて

1

これはおそらくこれらが匿名関数と呼ばれる理由です。 behaviorFoobehaviorBar、...これらの名前はこれらの無名関数に影響を与えません。この点を説明するために、このことを考慮してください。以上により

// this is a val! 
val behaviorFoo: Receive = { 
    case _ => 
    log.info(this.receive.getClass.getSimpleName) 
    become(behaviorBar) 
    self ! Ping 
} 
// this returns the same anonymous function 
def behaviorFoo2 = behaviorFoo 

、名前、その下匿名関数は無名関数自体には何の関係もありません保存することを確認する必要があり...

を今、あなたはこれらの匿名関数が何であるかを理解場合は、以下のようなものを行うことができます(彼らはタイプActor.Receiveでエイリアス部分関数、です):

// not an anonymous function anymore 
class BehaviourFoo extends Actor.Receive { 
    val anonymousFun: Actor.Receive = { 
    case _ => 
     log.info(this.receive.getClass.getSimpleName) 
     become(behaviorBar) 
     self ! Ping 
    } 
    override def isDefinedAt(x: Any) = anonymousFun.isDefinedAt(x) 

    override def apply(x: Any) = anonymousFun(x) 
} 
// again, the name behaviorFoo doesn't matter 
def behaviorFoo: Receive = new BehaviourFoo 

それは確かに面倒な価値はありませんが、それはあなたが何が起こっているか理解するのに役立つはずです。

+0

ありがとうございます!今分かります :) – HoTicE

関連する問題