2017-12-11 7 views
2

これは、Akka Cookbookの第10章の「Enveloping actor」のレシピに関する質問です。誰かがなぜ単に "ヘッダー"関数を引数として渡すことはできないのですか?代わりに、envelopingActorを作成する際に "ヘッダー_"として渡す必要がある理由を説明してください。この場合、関数名を引数として渡せないのはなぜですか?

元のコードはここで見つけることができます:https://github.com/PacktPublishing/Akka-Cookbook/tree/master/Chapter10/src/main/scala/com/packt/chapter10

package com.packt.chapter10 

import java.util.UUID 
import akka.actor.{Actor, ActorRef, ActorLogging, ActorSystem, Props} 
import Envelope._ 

object Envelope { 
    type Headers = Map[String, Any] 

    case class Envelope[T](msg: T, headers: Headers = Map.empty) 

} 

class EnvelopingActor(nextActor: ActorRef, addHeaders: Any => Headers) extends Actor { 
    def this(nextActor: ActorRef) = 
    this(nextActor, _ => Map()) 

    override def receive: Receive = { 
    case msg => nextActor ! new Envelope(msg, addHeaders(msg)) 
    } 
} 

class EnvelopeReceiver extends Actor with ActorLogging { 
    override def receive: Receive = { 
    case x => log.info(s"Received [$x]") 
    } 
} 

object EnvelopingActorApp extends App { 
    val actorSystem = ActorSystem() 
    val envelopeReceiver = actorSystem.actorOf(Props[EnvelopeReceiver], "receiver") 
    val envelopingActor = actorSystem.actorOf(
    Props(classOf[EnvelopingActor], envelopeReceiver, headers _)) 

    envelopingActor ! "Hello!" 

    def headers(msg: Any) = Map(
    "t" -> System.currentTimeMillis(), 
    "cId" -> UUID.randomUUID().toString 
) 
} 

答えて

3

削除しようとした場合_あなたは、このようなエラーが表示されることがあります。

Error:(379, 59) missing argument list for method headers in object EnvelopingActorApp
Unapplied methods are only converted to functions when a function type is expected.
You can make this conversion explicit by writing headers _ or headers(_) instead of headers .

を事がPropsがジェネリックであるということです任意のアクターパラメータセットのコンテナ。特に、いくつのパラメータがあるかは事前には分かりません。だから、次のシグネチャを使用しています:

def apply(clazz: Class[_], args: Any*): Props 

あなたはargsAny*の種類を持っていることを見ることができます。この*は、引数の数が可変であり、各引数がScala - Anyで利用可能な最も汎用的な型であることを意味します。これは関数型ではありません。

なぜScalaコンパイラがそのような場合にメソッドを関数型に自動的に変換しないのか - 私は答えは型安全だと思います。ある時点で、パラメータを取らなかったheadersがあったとします(したがって、headersは実質的にメソッドの呼び出しとなりました)。その後、1つのパラメータを取るように変更しました。 Anyはどの型とも一致するので、コンパイラはこれが実際には大きな変化であることに気づくことはできません(インプレースコールを後で呼び出される関数を渡すように変更しました)。パラメータが一部の関数型で強く型付けされている場合、コンパイラはその違いを認識して、自動的に変換を安全に行うことができます。

関連する問題